diff --git a/.gitignore b/.gitignore index 7d9d96c..9df513b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ *.retry -configs/*.mobileconfig -configs/*.p12 -configs/*.crt -configs/*.tmp +configs/* inventory_users diff --git a/digitalocean.yml b/digitalocean.yml index 4dbc3c9..687bfbc 100644 --- a/digitalocean.yml +++ b/digitalocean.yml @@ -1,3 +1,4 @@ +# vim:ft=ansible: - name: Configure the server and install required software hosts: localhost @@ -50,24 +51,29 @@ private: no - name: "dns_enabled" - prompt: "Do you want to install a local DNS resolver to block ads while surfing? (Y or N):\n" - default: "Y" + prompt: "Do you want to install a local DNS resolver to block ads while surfing? (y/n):\n" + default: "y" private: no - + - name: "proxy_enabled" - prompt: "Do you want to install a proxy to block ads and decrease traffic usage while surfing? (Y or N):\n" - default: "Y" - private: no + prompt: "Do you want to install an HTTP proxy to block ads and decrease traffic usage while surfing? (y/n):\n" + default: "y" + private: no - name: "auditd_enabled" - prompt: "Do you want to use auditd ? (Y or N):\n" - default: "Y" + prompt: "Do you want to use auditd for security monitoring (see config.cfg)? (y/n):\n" + default: "y" private: no - + + - name: "ssh_tunneling_enabled" + prompt: "Do you want each user to have their own account for SSH tunneling? (y/n):\n" + default: "y" + private: no + - name: "easyrsa_p12_export_password" - prompt: "Enter the password for p12 certificates:\n" - default: "vpn" - private: yes + prompt: "Enter a password for p12 certificates and SSH private keys: (minimum five characters)\n" + default: "vpnpw" + private: yes roles: - cloud-digitalocean @@ -125,10 +131,11 @@ roles: - common - security - - vpn - - { role: proxy, when: proxy_enabled is defined and proxy_enabled == "Y" } - - { role: dns_adblocking, when: dns_enabled is defined and dns_enabled == "Y" } - - { role: logging, when: auditd_enabled is defined and auditd_enabled == 'Y' } + - { role: proxy, when: proxy_enabled is defined and proxy_enabled == "y" } + - { role: dns_adblocking, when: dns_enabled is defined and dns_enabled == "y" } + - { role: logging, when: auditd_enabled is defined and auditd_enabled == "y" } + - { role: ssh_tunneling, when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" } + - vpn handlers: - name: reload eth0 diff --git a/ec2.yml b/ec2.yml index d88296e..a988be6 100644 --- a/ec2.yml +++ b/ec2.yml @@ -21,61 +21,65 @@ "11": "sa-east-1" vars_prompt: + - name: "aws_access_key" + prompt: "Enter your aws_access_key (http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html):\n" + private: yes - - name: "aws_access_key" - prompt: "Enter your aws_access_key (http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html):\n" - private: yes + - name: "aws_secret_key" + prompt: "Enter your aws_secret_key (http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html):\n" + private: yes - - name: "aws_secret_key" - prompt: "Enter your aws_secret_key (http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html):\n" - private: yes + - name: "region" + prompt: > + What region should the server be located in? + 1. us-east-1 US East (N. Virginia) + 2. us-west-1 US West (N. California) + 3. us-west-2 US West (Oregon) + 4. ap-south-1 Asia Pacific (Mumbai) + 5. ap-northeast-2 Asia Pacific (Seoul) + 6. ap-southeast-1 Asia Pacific (Singapore) + 7. ap-southeast-2 Asia Pacific (Sydney) + 8. ap-northeast-1 Asia Pacific (Tokyo) + 9. eu-central-1 EU (Frankfurt) + 10. eu-west-1 EU (Ireland) + 11. sa-east-1 South America (São Paulo) + default: "1" + private: no - - name: "region" - prompt: > - What region should the server be located in? - 1. us-east-1 US East (N. Virginia) - 2. us-west-1 US West (N. California) - 3. us-west-2 US West (Oregon) - 4. ap-south-1 Asia Pacific (Mumbai) - 5. ap-northeast-2 Asia Pacific (Seoul) - 6. ap-southeast-1 Asia Pacific (Singapore) - 7. ap-southeast-2 Asia Pacific (Sydney) - 8. ap-northeast-1 Asia Pacific (Tokyo) - 9. eu-central-1 EU (Frankfurt) - 10. eu-west-1 EU (Ireland) - 11. sa-east-1 South America (São Paulo) - default: "1" - private: no + - name: "aws_server_name" + prompt: "Name the vpn server:\n" + default: "algo.local" + private: no - - name: "aws_server_name" - prompt: "Name the vpn server:\n" - default: "algo.local" - private: no + - name: "ssh_public_key" + prompt: "Enter the local path to your SSH public key:\n" + default: "~/.ssh/id_rsa.pub" + private: no - - name: "ssh_public_key" - prompt: "Enter the local path to your SSH public key:\n" - default: "~/.ssh/id_rsa.pub" - private: no + - name: "dns_enabled" + prompt: "Do you want to install a local DNS resolver to block ads while surfing? (y/n):\n" + default: "y" + private: no - - name: "dns_enabled" - prompt: "Do you want to install a local DNS resolver to block ads while surfing? (Y or N):\n" - default: "Y" - private: no - - - name: "proxy_enabled" - prompt: "Do you want to install a proxy to block ads and decrease traffic usage while surfing? (Y or N):\n" - default: "Y" - private: no + - name: "proxy_enabled" + prompt: "Do you want to install an HTTP proxy to block ads and decrease traffic usage while surfing? (y/n):\n" + default: "y" + private: no - - name: "auditd_enabled" - prompt: "Do you want to use auditd ? (Y or N):\n" - default: "Y" - private: no - - - name: "easyrsa_p12_export_password" - prompt: "Enter the password for p12 certificates:\n" - default: "vpn" - private: yes + - name: "auditd_enabled" + prompt: "Do you want to use auditd for security monitoring (see config.cfg)? (y/n):\n" + default: "y" + private: no + + - name: "ssh_tunneling_enabled" + prompt: "Do you want each user to have their own account for SSH tunneling? (y/n):\n" + default: "y" + private: no + + - name: "easyrsa_p12_export_password" + prompt: "Enter a password for p12 certificates and SSH private keys: (minimum five characters)\n" + default: "vpnpw" + private: yes roles: - cloud-ec2 @@ -96,7 +100,8 @@ roles: - common - security - - vpn - - { role: proxy, when: proxy_enabled is defined and proxy_enabled == "Y" } - - { role: dns_adblocking , when: dns_enabled is defined and dns_enabled == "Y" } - - { role: logging, when: auditd_enabled is defined and auditd_enabled == 'Y' } + - { role: proxy, when: proxy_enabled is defined and proxy_enabled == "y" } + - { role: dns_adblocking , when: dns_enabled is defined and dns_enabled == "y" } + - { role: logging, when: auditd_enabled is defined and auditd_enabled == "y" } + - { role: ssh_tunneling, when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" } + - vpn diff --git a/gce.yml b/gce.yml index 6f1b452..24a0cb9 100644 --- a/gce.yml +++ b/gce.yml @@ -1,3 +1,4 @@ +# vim:ft=ansible: - name: Configure the server and install required software hosts: localhost gather_facts: false @@ -54,23 +55,28 @@ private: no - name: "dns_enabled" - prompt: "Do you want to install a local DNS resolver to block ads while surfing? (Y or N):\n" - default: "Y" + prompt: "Do you want to install a local DNS resolver to block ads while surfing? (y/n):\n" + default: "y" private: no - + - name: "proxy_enabled" - prompt: "Do you want to install a proxy to block ads and decrease traffic usage while surfing? (Y or N):\n" - default: "Y" + prompt: "Do you want to install an HTTP proxy to block ads and decrease traffic usage while surfing? (y/n):\n" + default: "y" private: no - name: "auditd_enabled" - prompt: "Do you want to use auditd ? (Y or N):\n" - default: "Y" + prompt: "Do you want to use auditd for security monitoring (see config.cfg)? (y/n):\n" + default: "y" private: no - + + - name: "ssh_tunneling_enabled" + prompt: "Do you want each user to have their own account for SSH tunneling? (y/n):\n" + default: "y" + private: no + - name: "easyrsa_p12_export_password" - prompt: "Enter the password for p12 certificates:\n" - default: "vpn" + prompt: "Enter a password for p12 certificates and SSH private keys: (minimum five characters)\n" + default: "vpnpw" private: yes roles: @@ -92,7 +98,8 @@ roles: - common - security - - vpn - - { role: proxy, when: proxy_enabled is defined and proxy_enabled == "Y" } - - { role: dns_adblocking , when: dns_enabled is defined and dns_enabled == "Y" } - - { role: logging, when: auditd_enabled is defined and auditd_enabled == 'Y' } + - { role: proxy, when: proxy_enabled is defined and proxy_enabled == "y" } + - { role: dns_adblocking , when: dns_enabled is defined and dns_enabled == "y" } + - { role: logging, when: auditd_enabled is defined and auditd_enabled == "y" } + - { role: ssh_tunneling, when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" } + - vpn diff --git a/non-cloud.yml b/non-cloud.yml index 0aca4fc..b1f9f65 100644 --- a/non-cloud.yml +++ b/non-cloud.yml @@ -1,42 +1,48 @@ +# vim:ft=ansible: - hosts: localhost gather_facts: False vars_files: - config.cfg + vars_prompt: + - name: "server_ip" + prompt: "Enter IP address of your server: (use localhost for local installation)\n" + default: localhost + private: no - - name: "server_ip" - prompt: "Enter IP address of your server: (use localhost for local installation)\n" - default: localhost - private: no + - name: "server_user" + prompt: "What user should we use to login on the server? (ignore if you're deploying to localhost):\n" + default: "root" + private: no - - name: "server_user" - prompt: "What user should we use to login on the server? (ignore if you're deploying to localhost):\n" - default: "root" - private: no + - name: "dns_enabled" + prompt: "Do you want to install a local DNS resolver to block ads while surfing? (y/n):\n" + default: "y" + private: no - - name: "dns_enabled" - prompt: "Do you want to install a local DNS resolver to block ads while surfing? (Y or N):\n" - default: "Y" - private: no + - name: "proxy_enabled" + prompt: "Do you want to install an HTTP proxy to block ads and decrease traffic usage while surfing? (y/n):\n" + default: "y" + private: no + + - name: "auditd_enabled" + prompt: "Do you want to use auditd for security monitoring (see config.cfg)? (y/n):\n" + default: "y" + private: no + + - name: "ssh_tunneling_enabled" + prompt: "Do you want each user to have their own account for SSH tunneling? (y/n):\n" + default: "y" + private: no + + - name: "easyrsa_p12_export_password" + prompt: "Enter a password for p12 certificates and SSH private keys: (minimum five characters)\n" + default: "vpnpw" + private: yes - - name: "proxy_enabled" - prompt: "Do you want to install a proxy to block ads and decrease traffic usage while surfing? (Y or N):\n" - default: "Y" - private: no - - - name: "auditd_enabled" - prompt: "Do you want to use auditd ? (Y or N):\n" - default: "Y" - private: no - - - name: "easyrsa_p12_export_password" - prompt: "Enter the password for p12 certificates:\n" - default: "vpn" - private: yes - - - name: "IP_subject" - prompt: "Enter public IP address of your server: (IMPORTANT! This IP is used to verify the certificate)\n" - private: no + - name: "IP_subject" + prompt: "Enter the public IP address of your server: (IMPORTANT! This IP is used to verify the certificate)\n" + private: no tasks: - name: Add the server to the vpn-host group @@ -47,6 +53,7 @@ ansible_python_interpreter: "/usr/bin/python2.7" dns_enabled: "{{ dns_enabled }}" proxy_enabled: "{{ proxy_enabled }}" + ssh_tunneling_enabled: "{{ ssh_tunneling_enabled }}" auditd_enabled: " {{ auditd_enabled }}" easyrsa_p12_export_password: "{{ easyrsa_p12_export_password }}" IP_subject: "{{ IP_subject }}" @@ -69,7 +76,8 @@ roles: - common - security - - vpn - - { role: proxy, when: proxy_enabled is defined and proxy_enabled == "Y" } - - { role: dns_adblocking , when: dns_enabled is defined and dns_enabled == "Y" } - - { role: logging, when: auditd_enabled is defined and auditd_enabled == 'Y' } + - { role: proxy, when: proxy_enabled is defined and proxy_enabled == "y" } + - { role: dns_adblocking , when: dns_enabled is defined and dns_enabled == "y" } + - { role: logging, when: auditd_enabled is defined and auditd_enabled == "y" } + - { role: ssh_tunneling, when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" } + - vpn diff --git a/roles/cloud-digitalocean/tasks/main.yml b/roles/cloud-digitalocean/tasks/main.yml index a7d5273..73e5c34 100644 --- a/roles/cloud-digitalocean/tasks/main.yml +++ b/roles/cloud-digitalocean/tasks/main.yml @@ -33,6 +33,7 @@ do_droplet_id: "{{ do.droplet.id }}" dns_enabled: "{{ dns_enabled }}" proxy_enabled: "{{ proxy_enabled }}" + ssh_tunneling_enabled: "{{ ssh_tunneling_enabled }}" auditd_enabled: " {{ auditd_enabled }}" easyrsa_p12_export_password: "{{ easyrsa_p12_export_password }}" cloud_provider: digitalocean diff --git a/roles/cloud-ec2/tasks/main.yml b/roles/cloud-ec2/tasks/main.yml index 13b897e..cb21189 100644 --- a/roles/cloud-ec2/tasks/main.yml +++ b/roles/cloud-ec2/tasks/main.yml @@ -71,6 +71,7 @@ ansible_python_interpreter: "/usr/bin/python2.7" dns_enabled: "{{ dns_enabled }}" proxy_enabled: "{{ proxy_enabled }}" + ssh_tunneling_enabled: "{{ ssh_tunneling_enabled }}" auditd_enabled: " {{ auditd_enabled }}" easyrsa_p12_export_password: "{{ easyrsa_p12_export_password }}" cloud_provider: ec2 diff --git a/roles/cloud-gce/tasks/main.yml b/roles/cloud-gce/tasks/main.yml index 4bddb27..661d9cb 100644 --- a/roles/cloud-gce/tasks/main.yml +++ b/roles/cloud-gce/tasks/main.yml @@ -22,6 +22,7 @@ ansible_python_interpreter: "/usr/bin/python2.7" dns_enabled: "{{ dns_enabled }}" proxy_enabled: "{{ proxy_enabled }}" + ssh_tunneling_enabled: "{{ ssh_tunneling_enabled }}" auditd_enabled: " {{ auditd_enabled }}" easyrsa_p12_export_password: "{{ easyrsa_p12_export_password }}" cloud_provider: gce diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 9752cc8..dc17b89 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -33,7 +33,7 @@ - name: SSH config template: src=sshd_config.j2 dest=/etc/ssh/sshd_config owner=root group=root mode=0644 notify: - - restart ssh + - restart ssh - name: Disable MOTD on login and SSHD replace: dest="{{ item.file }}" regexp="{{ item.regexp }}" replace="{{ item.line }}" @@ -70,7 +70,7 @@ lineinfile: dest=/etc/network/interfaces line='source /etc/network/interfaces.d/10-loopback-services.cfg' state=present notify: - restart loopback - + - meta: flush_handlers - name: Enable packet forwarding for IPv4 diff --git a/roles/common/templates/sshd_config.j2 b/roles/common/templates/sshd_config.j2 index d17d9f6..453a561 100644 --- a/roles/common/templates/sshd_config.j2 +++ b/roles/common/templates/sshd_config.j2 @@ -1,106 +1,64 @@ -# Package generated configuration file -# See the sshd_config(5) manpage for details - -# What ports, IPs and protocols we listen for Port 22 - -# Use these options to restrict which interfaces/protocols sshd will bind to -#ListenAddress :: -#ListenAddress 0.0.0.0 +# ListenAddress :: +# ListenAddress 0.0.0.0 Protocol 2 -# HostKeys for protocol version 2 -#HostKey /etc/ssh/ssh_host_rsa_key -#HostKey /etc/ssh/ssh_host_dsa_key -HostKey /etc/ssh/ssh_host_ecdsa_key -HostKey /etc/ssh/ssh_host_ed25519_key +# LogLevel VERBOSE logs user's key fingerprint on login. +# Needed to have a clear audit log of which keys were used to log in. +SyslogFacility AUTH +LogLevel VERBOSE -# Use kernel sandbox mechanisms where possible in unprivilegied processes +# Use kernel sandbox mechanisms where possible # Systrace on OpenBSD, Seccomp on Linux, seatbelt on MacOSX/Darwin, rlimit elsewhere. UsePrivilegeSeparation sandbox -# Lifetime and size of ephemeral version 1 server key -KeyRegenerationInterval 3600 -ServerKeyBits 1024 +# Handy for keeping network connections alive +TCPKeepAlive yes +ClientAliveInterval 120 -# Logging -SyslogFacility AUTH -LogLevel INFO - -# Authentication: -LoginGraceTime 120 +# Authentication +UsePAM yes PermitRootLogin without-password StrictModes yes - -RSAAuthentication no PubkeyAuthentication yes -#AuthorizedKeysFile %h/.ssh/authorized_keys - -# Don't read the user's ~/.rhosts and ~/.shosts files -IgnoreRhosts yes - -# For this to work you will also need host keys in /etc/ssh_known_hosts -RhostsRSAAuthentication no - -# similar for protocol version 2 -HostbasedAuthentication no - -# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication -#IgnoreUserKnownHosts yes - -# To enable empty passwords, change to yes (NOT RECOMMENDED) -PermitEmptyPasswords no - -# Change to yes to enable challenge-response passwords (beware issues with -# some PAM modules and threads) -ChallengeResponseAuthentication no - -# Change to no to disable tunnelled clear text passwords -PasswordAuthentication no - -# Kerberos options -#KerberosAuthentication no -#KerberosGetAFSToken no -#KerberosOrLocalPasswd yes -#KerberosTicketCleanup yes - -# GSSAPI options -#GSSAPIAuthentication no -#GSSAPICleanupCredentials yes - -X11Forwarding no -X11DisplayOffset 10 -PrintMotd no -PrintLastLog yes -TCPKeepAlive yes -#UseLogin no - -#MaxStartups 10:30:60 -#Banner /etc/issue.net - -# Allow client to pass locale environment variables AcceptEnv LANG LC_* -# Subsystem sftp /usr/lib/openssh/sftp-server - -# Set this to 'yes' to enable PAM authentication, account processing, -# and session processing. If this is enabled, PAM authentication will -# be allowed through the ChallengeResponseAuthentication and -# PasswordAuthentication. Depending on your PAM configuration, -# PAM authentication via ChallengeResponseAuthentication may bypass -# the setting of "PermitRootLogin yes -# If you just want the PAM account and session checks to run without -# PAM authentication, then enable this but set PasswordAuthentication -# and ChallengeResponseAuthentication to 'no'. -UsePAM yes - -# Added by DigitalOcean build process -ClientAliveInterval 120 -ClientAliveCountMax 2 +# Turn off a lot of features +IgnoreRhosts yes +RhostsRSAAuthentication no +RSAAuthentication no +HostbasedAuthentication no +PermitEmptyPasswords no +ChallengeResponseAuthentication no +PasswordAuthentication no UseDNS no + +# Do not enable sftp +# If you DO enable it, use this line to log which files sftp users read/write +# Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO + +# This makes ansible faster +PrintMotd no +PrintLastLog yes + +# Use only modern host keys +HostKey /etc/ssh/ssh_host_ecdsa_key +HostKey /etc/ssh/ssh_host_ed25519_key + +# Use only modern ciphers +KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com -KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256 +# TODO: I haven't seen anyone review these yet +# HostKeyAlgorithms ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519 +# TODO: I haven't seen anyone review these yet +# PubkeyAcceptedKeyTypes ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519 -# Password based logins are disabled - only public key based logins are allowed. -AuthenticationMethods publickey +{% if ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" %} +Match Group algo + AllowTcpForwarding remote + AllowAgentForwarding no + AllowStreamLocalForwarding no + PermitTunnel no + X11Forwarding no +{% endif %} diff --git a/roles/dns_adblocking/tasks/main.yml b/roles/dns_adblocking/tasks/main.yml index df0fc37..a37bf9c 100644 --- a/roles/dns_adblocking/tasks/main.yml +++ b/roles/dns_adblocking/tasks/main.yml @@ -8,24 +8,24 @@ template: src=usr.sbin.dnsmasq.j2 dest=/etc/apparmor.d/usr.sbin.dnsmasq owner=root group=root mode=0600 notify: - restart dnsmasq - + - name: The dnsmasq directory created - file: dest=/var/lib/dnsmasq state=directory mode=755 owner=dnsmasq group=nogroup + file: dest=/var/lib/dnsmasq state=directory mode=0755 owner=dnsmasq group=nogroup - name: Enforce the dnsmasq AppArmor policy shell: aa-enforce usr.sbin.dnsmasq - name: Ensure that the dnsmasq service directory exist file: path=/etc/systemd/system/dnsmasq.service.d/ state=directory mode=0755 owner=root group=root - + - name: Setup the cgroup limitations for the ipsec daemon template: src=100-CustomLimitations.conf.j2 dest=/etc/systemd/system/dnsmasq.service.d/100-CustomLimitations.conf notify: - - daemon-reload + - daemon-reload - restart dnsmasq - -- meta: flush_handlers - + +- meta: flush_handlers + - name: Dnsmasq configured template: src=dnsmasq.conf.j2 dest=/etc/dnsmasq.conf notify: @@ -35,7 +35,7 @@ template: src=adblock.sh dest=/opt/adblock.sh owner=root group=root mode=0755 - name: Adblock script added to cron - cron: + cron: name: Adblock hosts update minute: 10 hour: 2 diff --git a/roles/proxy/handlers/main.yml b/roles/proxy/handlers/main.yml index bea23c7..a31941b 100644 --- a/roles/proxy/handlers/main.yml +++ b/roles/proxy/handlers/main.yml @@ -1,8 +1,8 @@ - name: restart privoxy service: name=privoxy state=restarted - + - name: daemon-reload - shell: systemctl daemon-reload + shell: systemctl daemon-reload - name: restart apparmor service: name=apparmor state=restarted diff --git a/roles/proxy/tasks/main.yml b/roles/proxy/tasks/main.yml index 1157a97..81dbcab 100644 --- a/roles/proxy/tasks/main.yml +++ b/roles/proxy/tasks/main.yml @@ -16,17 +16,17 @@ - name: Enforce the privoxy AppArmor policy shell: aa-enforce usr.sbin.privoxy - + - name: Ensure that the privoxy service directory exist file: path=/etc/systemd/system/privoxy.service.d/ state=directory mode=0755 owner=root group=root - + - name: Setup the cgroup limitations for the privoxy daemon template: src=privoxy_100-CustomLimitations.conf.j2 dest=/etc/systemd/system/privoxy.service.d/100-CustomLimitations.conf notify: - - daemon-reload + - daemon-reload - restart privoxy - -- meta: flush_handlers + +- meta: flush_handlers - name: Privoxy enabled and started service: name=privoxy state=started enabled=yes @@ -70,14 +70,14 @@ template: src=ports.conf.j2 dest=/etc/apache2/ports.conf notify: - restart apache2 - + - name: Ensure that the apache2 service directory exist file: path=/etc/systemd/system/apache2.service.d/ state=directory mode=0755 owner=root group=root - + - name: Setup the cgroup limitations for the apache2 daemon template: src=apache2_100-CustomLimitations.conf.j2 dest=/etc/systemd/system/apache2.service.d/100-CustomLimitations.conf notify: - - daemon-reload + - daemon-reload - restart apache2 - -- meta: flush_handlers + +- meta: flush_handlers diff --git a/roles/security/handlers/main.yml b/roles/security/handlers/main.yml index f5fb1c9..ad1168b 100644 --- a/roles/security/handlers/main.yml +++ b/roles/security/handlers/main.yml @@ -1,8 +1,8 @@ - name: restart rsyslog service: name=rsyslog state=restarted - + - name: restart iptables service: name=netfilter-persistent state=restarted - + - name: flush routing cache shell: echo 1 > /proc/sys/net/ipv4/route/flush diff --git a/roles/security/tasks/main.yml b/roles/security/tasks/main.yml index 10d31eb..a528896 100644 --- a/roles/security/tasks/main.yml +++ b/roles/security/tasks/main.yml @@ -97,6 +97,6 @@ template: src="{{ item.src }}" dest="{{ item.dest }}" owner=root group=root mode=0640 with_items: - { src: rules.v4.j2, dest: /etc/iptables/rules.v4 } - - { src: rules.v6.j2, dest: /etc/iptables/rules.v6 } + - { src: rules.v6.j2, dest: /etc/iptables/rules.v6 } notify: - restart iptables diff --git a/roles/ssh_tunneling/handlers/main.yml b/roles/ssh_tunneling/handlers/main.yml new file mode 100644 index 0000000..276ebfe --- /dev/null +++ b/roles/ssh_tunneling/handlers/main.yml @@ -0,0 +1,2 @@ +- name: restart ssh + service: name=ssh state=restarted diff --git a/roles/ssh_tunneling/tasks/main.yml b/roles/ssh_tunneling/tasks/main.yml new file mode 100644 index 0000000..2402f8f --- /dev/null +++ b/roles/ssh_tunneling/tasks/main.yml @@ -0,0 +1,49 @@ +--- + +- name: Ensure that the algo group exist + group: name=algo state=present + +- name: Ensure that the jail directory exist + file: path=/var/jail/ state=directory mode=0755 owner=root group=root + +- name: Ensure that the SSH users exist + user: + name: "{{ item }}" + groups: algo + home: '/var/jail/{{ item }}' + createhome: yes + generate_ssh_key: yes + shell: /bin/false + ssh_key_type: rsa + ssh_key_bits: 2048 + ssh_key_comment: '{{ item }}@{{ IP_subject_alt_name }}' + ssh_key_passphrase: "{{ easyrsa_p12_export_password }}" + state: present + append: yes + with_items: "{{ users }}" + +- name: The authorized keys file created + file: + src: '/var/jail/{{ item }}/.ssh/id_rsa.pub' + dest: '/var/jail/{{ item }}/.ssh/authorized_keys' + owner: "{{ item }}" + group: "{{ item }}" + state: link + with_items: "{{ users }}" + +- name: Generate SSH fingerprints + shell: > + ssh-keyscan {{ IP_subject_alt_name }} 2>/dev/null + register: ssh_fingerprints + +- name: The known_hosts file created + template: src=known_hosts.j2 dest=/root/.ssh/{{ IP_subject_alt_name }}_known_hosts + +- name: Fetch users SSH private keys + fetch: src='/var/jail/{{ item }}/.ssh/id_rsa' dest=configs/{{ IP_subject_alt_name }}_{{ item }}.ssh.pem flat=yes + with_items: "{{ users }}" + +- name: Fetch the known_hosts file + fetch: src='/root/.ssh/{{ IP_subject_alt_name }}_known_hosts' dest=configs/{{ IP_subject_alt_name }}_known_hosts flat=yes + + diff --git a/roles/ssh_tunneling/templates/known_hosts.j2 b/roles/ssh_tunneling/templates/known_hosts.j2 new file mode 100644 index 0000000..98d33c4 --- /dev/null +++ b/roles/ssh_tunneling/templates/known_hosts.j2 @@ -0,0 +1,3 @@ +{% for item in ssh_fingerprints.stdout_lines %} +{{ item }} +{% endfor %} diff --git a/roles/vpn/handlers/main.yml b/roles/vpn/handlers/main.yml index c5dcdc9..a3c10f7 100644 --- a/roles/vpn/handlers/main.yml +++ b/roles/vpn/handlers/main.yml @@ -1,6 +1,6 @@ - name: restart strongswan service: name=strongswan state=restarted - + - name: daemon-reload shell: systemctl daemon-reload diff --git a/roles/vpn/tasks/main.yml b/roles/vpn/tasks/main.yml index 1592db4..1fe08b9 100644 --- a/roles/vpn/tasks/main.yml +++ b/roles/vpn/tasks/main.yml @@ -1,6 +1,6 @@ - name: Gather Facts setup: - + - name: Install StrongSwan apt: name=strongswan state=latest update_cache=yes @@ -19,28 +19,28 @@ - apparmor - strongswan - netfilter-persistent - + - name: Ensure that the strongswan group exist group: name=strongswan state=present - + - name: Ensure that the strongswan user exist user: name=strongswan group=strongswan state=present - + - name: Ensure that the strongswan service directory exist file: path=/etc/systemd/system/strongswan.service.d/ state=directory mode=0755 owner=root group=root - + - name: Setup the cgroup limitations for the ipsec daemon template: src=100-CustomLimitations.conf.j2 dest=/etc/systemd/system/strongswan.service.d/100-CustomLimitations.conf notify: - - daemon-reload + - daemon-reload - restart strongswan - -- meta: flush_handlers - + +- meta: flush_handlers + - name: Setup the strongswan.conf file from our template template: src=strongswan.conf.j2 dest=/etc/strongswan.conf owner=root group=root mode=0644 notify: - - restart strongswan + - restart strongswan - name: Setup the ipsec.conf file from our template template: src=ipsec.conf.j2 dest=/etc/ipsec.conf owner=root group=root mode=0644 @@ -148,11 +148,11 @@ - name: Fetch users mobileconfig fetch: src=/{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.mobileconfig dest=configs/{{ IP_subject_alt_name }}_{{ item }}.mobileconfig flat=yes with_items: "{{ users }}" - + - name: Restrict permissions file: path="{{ item }}" state=directory mode=0700 owner=strongswan group=root with_items: - - /etc/ipsec.d/private + - /etc/ipsec.d/private - name: Fetch server CA certificate fetch: src=/{{ easyrsa_dir }}/easyrsa3/pki/ca.crt dest=configs/{{ IP_subject_alt_name }}_ca.crt flat=yes diff --git a/users.yml b/users.yml index 2e9e37e..9154457 100644 --- a/users.yml +++ b/users.yml @@ -14,12 +14,17 @@ - name: "server_user" prompt: "What user should we use to login on the server? (ignore if you're deploying to localhost):\n" default: "root" - private: no + private: no + + - name: "ssh_tunneling_enabled" + prompt: "Do you want each user to have their own account for SSH tunneling? (y/n):\n" + default: "y" + private: no - name: "easyrsa_p12_export_password" - prompt: "Enter the password for p12 certificates:\n" - default: "vpn" - private: yes + prompt: "Enter a password for p12 certificates and SSH private keys: (minimum five characters)\n" + default: "vpnpw" + private: yes - name: "IP_subject" prompt: "Enter public IP address of your server: (IMPORTANT! This IP is used to verify the certificate)\n" @@ -33,6 +38,7 @@ ansible_ssh_user: "{{ server_user }}" ansible_python_interpreter: "/usr/bin/python2.7" easyrsa_p12_export_password: "{{ easyrsa_p12_export_password }}" + ssh_tunneling_enabled: "{{ ssh_tunneling_enabled }}" IP_subject: "{{ IP_subject }}" - name: Wait for SSH to become available @@ -114,3 +120,51 @@ - name: Fetch server CA certificate fetch: src=/{{ easyrsa_dir }}/easyrsa3/pki/ca.crt dest=configs/{{ IP_subject_alt_name }}_ca.crt flat=yes + + # SSH + + - name: SSH | Ensure that the system users exist + user: + name: "{{ item }}" + groups: algo + home: '/var/jail/{{ item }}' + createhome: yes + generate_ssh_key: yes + shell: /bin/false + ssh_key_type: rsa + ssh_key_bits: 2048 + ssh_key_comment: '{{ item }}@{{ IP_subject_alt_name }}' + ssh_key_passphrase: "{{ easyrsa_p12_export_password }}" + state: present + append: yes + with_items: "{{ users }}" + when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" + + - name: SSH | The authorized keys file created + file: + src: '/var/jail/{{ item }}/.ssh/id_rsa.pub' + dest: '/var/jail/{{ item }}/.ssh/authorized_keys' + owner: "{{ item }}" + group: "{{ item }}" + state: link + with_items: "{{ users }}" + when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" + + - name: SSH | Get active system users + shell: > + getent group algo | cut -f4 -d: | sed "s/,/\n/g" + register: valid_users + when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" + + - name: SSH | Delete non-existing users + user: + name: "{{ item }}" + state: absent + remove: yes + force: yes + when: item not in users and ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" + with_items: "{{ valid_users.stdout_lines }}" + + - name: SSH | Fetch users SSH private keys + fetch: src='/var/jail/{{ item }}/.ssh/id_rsa' dest=configs/{{ IP_subject_alt_name }}_{{ item }}.ssh.pem flat=yes + with_items: "{{ users }}"