I have configured one of my servers as Open connect VPN and WordPress Server. The server shares port 443 for Apache and Openconnect using HAproxy. I had to migrate the services to a new VM therefore I had to build the setup from scratch. To save time in future, I have automated the steps to configure the server using Ansible.
Prerequisites
The code assumes that
- You have a server with public IP address.
- You have root access to the instance.
- You have added A-records for your VPN domain and WordPress domains and mapped those to the public IP of the instance.
Step 1: Install Git and Epel repository
Login to the server and switch to root.
su -
yum install git epel-release -y
Step 2: Install Ansible
Install Ansible package from EPEL repository
yum install ansible -y
Step 3: Clone the Repository
Clone the repository
git clone https://github.com/induslevel/server-setup-via-ansible.git
Output
Cloning into 'server-setup-via-ansible'...
remote: Enumerating objects: 27, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 27 (delta 1), reused 5 (delta 0), pack-reused 12 (from 1)
Unpacking objects: 100% (27/27), done.
Step 4: Update the Secrets
There are few variables defined in the var/common_vars.yml that you will need to update according to your setup
The repository has default values for secrets which are set to ‘your_secure_password_here‘ and vault password is set to ‘your_vault_password‘. You will need to setup your own secret values and vault password.
The following commands will overwrite existing encrypted values with new ones.
cd server-setup-via-ansible
echo 'your_vault_password' > ~/.vault_pass.txt
chmod 600 ~/.vault_pass.txt
echo "---" > vars/secrets.yml # Add header to the file
ansible-vault encrypt_string 'your_secure_password_here' --name 'static_db_password' --vault-password-file ~/.vault_pass.txt >> vars/secrets.yml
echo "" >> vars/secrets.yml # Adding line
echo "" >> vars/secrets.yml # Adding line
ansible-vault encrypt_string 'your_secure_password_here' --name 'vpn_user_password' --vault-password-file ~/.vault_pass.txt >> vars/secrets.yml
echo "" >> vars/secrets.yml # Adding line
cat vars/secrets.yml
Output
---
static_db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
31336232366363326633663163613932616465373561613739636264363030303
3466633461663331356436363133393561346331653835350a386564313838386
34363532663161646565366536626239363965336430633065373735386530376
3431393663333437300a373131643937323937383637303032663131393536656
35316564303064623836303865383135616362623966326538643934393739643
vpn_user_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
616639396238663635343337303138353435393936643964353138663666333336
6336643165303433623533303137376163363939343936380a6635653831326236
303163326137613239623261626131366463363231663936393838356362663639
3339616334343161310a6663353063633639313364363139326364326164393632
336136653738366433616664383838383533353536663937633439323835626264
Step 5: Update the Domain Names
#Domain that will be to use to connect to VPN. Add single domain here
haproxy_vpn_domains:
- eu-vpn.induslevel.com
#Domains that will be used for WordPress websites. Multiple domains can be added
haproxy_wordpress_domains:
- webserver.induslevel.com
- webserver2.induslevel.com
# Let's Encrypt email address where you will get notification for cert expiry
letsencrypt_email: [email protected]
# Certbot dry run mode (set to true for dry run, false for production)
#certbot_dry_run: true # Change to false for production
certbot_dry_run: false # Change to false for production
#Get test certificate
#Change value to false if you want to run for production setup.
#Keep in mind there are limit for getting certificates so use staging option during testing
certbot_staging_cert: true
#IPs will be assigned to VPN clients from this subnet.
vpn_ipv4_network: "192.168.250.0/24" # Replace this with the desired subnet that is not being used in your existing network
Step 5: Run the Playbook
Run the playbook to deploy the setup
ansible-playbook --vault-password-file ~/.vault_pass.txt playbooks/site.yml
Output
PLAY [Setup HAProxy] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************
ok: [localhost]
TASK [Gather SELinux facts] ***************************************************************************************************
ok: [localhost]
TASK [Ensure SELinux is permissive if currently enforcing] ***************************************************************************************************
skipping: [localhost]
TASK [Disable SELinux permanently] **************************************************************************************************
ok: [localhost]
TASK [Gather all facts] **************************************************************************************************
ok: [localhost]
TASK [Find default IP address] *************************************************************************************************
ok: [localhost]
TASK [Install HAProxy] ***********************************************************************************************
changed: [localhost]
TASK [Configure HAProxy] **********************************************************************************************
changed: [localhost]
TASK [Start HAProxy service]
**********************************************************************************************
changed: [localhost]
TASK [Install firewalld] ************************************************************************************************
ok: [localhost]
TASK [Start firewalld service] ***********************************************************************************************
changed: [localhost]
TASK [Allow traffic on port 443] ***********************************************************************************************
changed: [localhost]
TASK [Set default deny policy] ************************************************************************************************
changed: [localhost]
TASK [Reload firewalld to apply changes] ************************************************************************************************
changed: [localhost]
TASK [Allow traffic on port 80] ***********************************************************************************************
changed: [localhost]
TASK [Reload firewalld to apply changes] ***********************************************************************************************
changed: [localhost]
RUNNING HANDLER [Restart HAProxy] ************************************************************************************************
changed: [localhost]
PLAY [Setup Let's Encrypt certificates for HAProxy domains (Apache)] ************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [localhost]
TASK [Ensure EPEL repository is enabled (required for Certbot)] ***********************************************************************************************
ok: [localhost]
TASK [Install firewalld] **********************************************************************************************
ok: [localhost]
TASK [Start firewalld service] **********************************************************************************************
ok: [localhost]
TASK [Install necessary packages for Let's Encrypt and Apache SSL support] *********************************************************************************************
changed: [localhost]
TASK [Comment out all uncommented lines in welcome.conf] ********************************************************************************************
changed: [localhost]
TASK [Update ssl.conf to listen on 127.0.0.2:443] *********************************************************************************************
changed: [localhost]
TASK [Update VirtualHost to listen on 127.0.0.2:443] ********************************************************************************************
changed: [localhost]
TASK [Allow port 80 in the firewall if not already allowed] *********************************************************************************************
ok: [localhost]
TASK [Allow port 443 in the firewall if not already allowed] **********************************************************************************************
ok: [localhost]
TASK [Check if document root exists for haproxy_vpn_domains] *********************************************************************************************
ok: [localhost] => (item=eu-vpn.induslevel.com)
TASK [Create document root directories for haproxy_vpn_domains if they don't exist] ************************************************************************************
changed: [localhost] => (item=eu-vpn.induslevel.com)
TASK [Check if document root exists for haproxy_wordpress_domains] *****************************************************************************************
ok: [localhost] => (item=webserver.induslevel.com)
ok: [localhost] => (item=webserver2.induslevel.com)
TASK [Create document root directories for haproxy_wordpress_domains if they don't exist] ******************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
TASK [Start and enable Apache service] *****************************************************************************************
changed: [localhost]
TASK [Check if SSL configuration file already exists for haproxy_wordpress_domains] ************************************************************************************
ok: [localhost] => (item=webserver.induslevel.com)
ok: [localhost] => (item=webserver2.induslevel.com)
TASK [Create Apache conf for haproxy_wordpress_domains using WordPress template] ***************************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
TASK [Create Apache conf for haproxy_vpn_domains using WordPress template] ********************************************************************************************
changed: [localhost] => (item=eu-vpn.induslevel.com)
TASK [Reload Apache before certbot command] ***************************************************************************************
ok: [localhost]
TASK [Obtain Let's Encrypt certificates using Certbot for haproxy_vpn_domains] *****************************************************************************************
changed: [localhost] => (item=eu-vpn.induslevel.com)
TASK [Obtain Let's Encrypt certificates using Certbot for haproxy_wordpress_domains] ***********************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
TASK [Update HTTPS configuration files for haproxy_wordpress_domains] ******************************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
RUNNING HANDLER [reload_apache] ********************************************************************************************
changed: [localhost]
PLAY [Setup WordPress for multiple domains] ******************************************************************************************
TASK [Gathering Facts] *******************************************************************************************
ok: [localhost]
TASK [Check if MariaDB 10.11 module is enabled] *******************************************************************************************
ok: [localhost]
TASK [Set fact if MariaDB 10.11 module is enabled]
********************************************************************************************
ok: [localhost]
TASK [Enable the MariaDB 10.11 module if not already enabled] ********************************************************************************************
skipping: [localhost]
TASK [Install mariadb-devel with devel repository enabled] ********************************************************************************************
changed: [localhost]
TASK [Install required packages] *********************************************************************************************
changed: [localhost]
TASK [Install Python MySQL client library (mysqlclient)] ********************************************************************************************
changed: [localhost]
TASK [Start and enable MariaDB service] ********************************************************************************************
changed: [localhost]
TASK [Start and enable Apache service] ********************************************************************************************
ok: [localhost]
TASK [Start and enable php-fpm service] ********************************************************************************************
changed: [localhost]
TASK [Allow port 80 in the firewall if not already allowed] *********************************************************************************************
ok: [localhost]
TASK [Ensure the web root directory exists] ********************************************************************************************
ok: [localhost] => (item=webserver.induslevel.com)
ok: [localhost] => (item=webserver2.induslevel.com)
TASK [Download WordPress tarball] *******************************************************************************************
changed: [localhost]
TASK [Copy WordPress tarball to each domain root] *******************************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
TASK [Extract WordPress tarball into the document root] ******************************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
TASK [Create databases for each WordPress domain] ******************************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
TASK [Create database users and grant privileges for each domain] *****************************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
TASK [Check if wp-config.php exists for each domain] ****************************************************************************************
ok: [localhost] => (item=webserver.induslevel.com)
ok: [localhost] => (item=webserver2.induslevel.com)
TASK [Set fact for wp-config.php existence] ****************************************************************************************
ok: [localhost]
TASK [Set up WordPress configuration for each domain] ****************************************************************************************
changed: [localhost] => (item=webserver.induslevel.com)
changed: [localhost] => (item=webserver2.induslevel.com)
TASK [Configure Apache for each WordPress site] *****************************************************************************************
ok: [localhost] => (item=webserver.induslevel.com)
ok: [localhost] => (item=webserver2.induslevel.com)
TASK [Reload Apache to apply changes] *****************************************************************************************
ok: [localhost]
PLAY [Setup OpenConnect VPN] *****************************************************************************************
TASK [Gathering Facts] *****************************************************************************************
ok: [localhost]
TASK [Install OpenConnect VPN server and firewalld] ***********************************************************************************
changed: [localhost]
TASK [Ensure firewalld is started and enabled] **********************************************************************************
ok: [localhost]
TASK [Open TCP port 443 in firewalld] **********************************************************************************
ok: [localhost]
TASK [Open UDP port 443 in firewalld] **********************************************************************************
changed: [localhost]
TASK [Enable masquerading in firewalld] ***********************************************************************************
changed: [localhost]
TASK [Reload firewalld if there are changes] ***********************************************************************************
changed: [localhost]
TASK [Enable IP forwarding in sysctl] ***********************************************************************************
changed: [localhost]
TASK [Ensure IP forwarding is persistent across reboots] **********************************************************************************
changed: [localhost]
TASK [Reload sysctl to apply IP forwarding changes if necessary] **********************************************************************************
changed: [localhost]
TASK [Deploy ocserv configuration file] ***********************************************************************************
changed: [localhost]
TASK [Check if ocpasswd file exists] ***********************************************************************************
ok: [localhost]
TASK [Ensure ocpasswd file exists with the correct permissions] ************************************************************************************
changed: [localhost]
TASK [Decrypt VPN user password] ***********************************************************************************
ok: [localhost]
TASK [Check if VPN user exists in ocpasswd] ************************************************************************************
ok: [localhost]
TASK [Create VPN user and add to ocpasswd] ************************************************************************************
ok: [localhost]
TASK [Ensure ocserv service is started and enabled] **************************************************************************************
changed: [localhost]
PLAY RECAP ****************************************************************************
localhost: ok=77 changed=44 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
Step 6: Rerun the Playbook
Rerun the playbook once again to ensure that there is no pending change.
ansible-playbook --vault-password-file ~/.vault_pass.txt playbooks/site.yml
Output
PLAY [Setup HAProxy]
**************************************************************************************************************
TASK [Gathering Facts]
***************************************************************************************************************
ok: [localhost]
TASK [Gather SELinux facts]
****************************************************************************************************************
ok: [localhost]
.
.
.
TASK [Ensure ocserv service is started and enabled]
*****************************************************************************************************
ok: [localhost]
PLAY RECAP
******************************************************************************************************
localhost : ok=65 changed=0 unreachable=0 failed=0 skipped=12 rescued=0 ignored=0
Final Step: Check the Website
At this stage, you will be able to access the WordPress website
Following this guide to connect to VPN Server