diff --git a/README.md b/README.md index cd5db96..e25e280 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ A collection of delicious docker recipes. - [x] shadowvpn - [x] snort :beetle: - [x] squid +- [x] strongswan :+1: - [x] swarm-arm - [x] taskd - [x] telegraf diff --git a/strongswan/Dockerfile b/strongswan/Dockerfile new file mode 100644 index 0000000..f691661 --- /dev/null +++ b/strongswan/Dockerfile @@ -0,0 +1,25 @@ +# +# Dockerfile for ipsec +# + +FROM alpine +MAINTAINER kev + +RUN set -xe \ + && apk add --no-cache iptables openssl strongswan util-linux \ + && ln -sf /etc/ipsec.d/ipsec.conf /etc/ipsec.conf \ + && ln -sf /etc/ipsec.d/ipsec.secrets /etc/ipsec.secrets + +COPY init.sh / + +VOLUME /etc/ipsec.d /etc/strongswan.d + +ENV VPN_SUBNET=10.20.30.0/24 + +EXPOSE 500/udp 4500/udp + +CMD set -xe \ + && /init.sh \ + && sysctl -w net.ipv4.ip_forward=1 \ + && iptables -t nat -A POSTROUTING -s $VPN_SUBNET -o eth0 -j MASQUERADE \ + && ipsec start --nofork diff --git a/strongswan/README.md b/strongswan/README.md new file mode 100644 index 0000000..b05b6df --- /dev/null +++ b/strongswan/README.md @@ -0,0 +1,45 @@ +strongswan +========== + +![](https://badge.imagelayers.io/vimagick/strongswan:latest.svg) + +[strongSwan][1] is an Open Source IPsec-based VPN solution for Linux and other +UNIX based operating systems implementing both the IKEv1 and IKEv2 key exchange +protocols. + +> :warning: This docker image only support IKEv2! + +### docker-compose.yml + +```yaml +strongswan: + image: vimagick/strongswan + ports: + - 500:500/udp + - 4500:4500/udp + volumes: + - ./log:/var/log + - /lib/modules:/lib/modules + - /etc/localtime:/etc/localtime + environment: + - VPN_DOMAIN=vpn.easypi.info + - VPN_DNS=8.8.8.8 + - VPN_SUBNET=10.20.30.0/24 + - VPN_P12_PASSWORD=secret + cap_add: + - NET_ADMIN + privileged: yes + restart: always +``` + +### up and running + +```bash +docker-compose up -d +docker cp strongswan_strongswan_1:/etc/ipsec.d/client.mobileconfig . +tail -f log/charon.log +``` + +> File `client.mobileconfig` can be imported into MacOSX as `VPN (IKEv2)`. + +[1]: https://strongswan.org/ diff --git a/strongswan/docker-compose.yml b/strongswan/docker-compose.yml new file mode 100644 index 0000000..037347f --- /dev/null +++ b/strongswan/docker-compose.yml @@ -0,0 +1,18 @@ +strongswan: + image: vimagick/strongswan + ports: + - 500:500/udp + - 4500:4500/udp + volumes: + - ./log:/var/log + - /lib/modules:/lib/modules + - /etc/localtime:/etc/localtime + environment: + - VPN_DOMAIN=vpn.easypi.info + - VPN_DNS=8.8.8.8 + - VPN_SUBNET=10.20.30.0/24 + - VPN_P12_PASSWORD=secret + cap_add: + - NET_ADMIN + privileged: yes + restart: always diff --git a/strongswan/init.sh b/strongswan/init.sh new file mode 100755 index 0000000..b997175 --- /dev/null +++ b/strongswan/init.sh @@ -0,0 +1,281 @@ +#!/bin/sh +# +# gen config files for strongswan +# +# - VPN_SUBNET +# - VPN_DOMAIN +# - VPN_DNS +# - VPN_P12_PASSWORD +# + +if [ -e /etc/ipsec.d/ipsec.conf ] +then + echo "Already Initialized!" + exit 0 +fi + +cat > /etc/ipsec.d/ipsec.conf <<_EOF_ +config setup + uniqueids=never + +conn %default + keyexchange=ike + dpdaction=clear + dpddelay=300s + rekey=no + left=%any + leftsubnet=0.0.0.0/0 + right=%any + +conn IKE-BASE + leftca=ca.cert.pem + leftcert=server.cert.pem + rightsourceip=${VPN_SUBNET} + +conn IPSec-IKEv2 + also=IKE-BASE + keyexchange=ikev2 + ike=aes256-sha256-modp1024,3des-sha1-modp1024,aes256-sha1-modp1024! + esp=aes256-sha256,3des-sha1,aes256-sha1! + leftid="${VPN_DOMAIN}" + leftsendcert=always + leftauth=pubkey + rightauth=pubkey + rightid="client.${VPN_DOMAIN}" + rightcert=client.cert.pem + auto=add +_EOF_ + + +cat > /etc/ipsec.d/ipsec.secrets <<_EOF_ +: RSA server.pem +_EOF_ + + +cat > /etc/strongswan.d/charon.conf <<_EOF_ +charon { + duplicheck.enable = no + dns1 = ${VPN_DNS} + filelog { + /var/log/charon.log { + time_format = %b %e %T + ike_name = yes + append = yes + default = 1 + flush_line = yes + } + } + user = root +} +_EOF_ + + +# gen ca key and cert +ipsec pki --gen --outform pem > /etc/ipsec.d/private/ca.pem + +ipsec pki --self \ + --in /etc/ipsec.d/private/ca.pem \ + --dn "C=CN, O=ING, CN=StrongSwan CA" \ + --ca \ + --lifetime 3650 \ + --outform pem > /etc/ipsec.d/cacerts/ca.cert.pem + +# gen server key and cert +ipsec pki --gen --outform pem > /etc/ipsec.d/private/server.pem + +ipsec pki --pub --in /etc/ipsec.d/private/server.pem | + ipsec pki --issue --lifetime 1200 --cacert /etc/ipsec.d/cacerts/ca.cert.pem \ + --cakey /etc/ipsec.d/private/ca.pem --dn "C=CN, O=ING, CN=${VPN_DOMAIN}" \ + --san="${VPN_DOMAIN}" --flag serverAuth --flag ikeIntermediate \ + --outform pem > /etc/ipsec.d/certs/server.cert.pem + +# gen client key and cert +ipsec pki --gen --outform pem > /etc/ipsec.d/private/client.pem + +ipsec pki --pub --in /etc/ipsec.d/private/client.pem | + ipsec pki --issue \ + --cacert /etc/ipsec.d/cacerts/ca.cert.pem \ + --cakey /etc/ipsec.d/private/ca.pem --dn "C=CN, O=ING, CN=client.${VPN_DOMAIN}" \ + --san="client.${VPN_DOMAIN}" \ + --outform pem > /etc/ipsec.d/certs/client.cert.pem + +openssl pkcs12 -export \ + -inkey /etc/ipsec.d/private/client.pem \ + -in /etc/ipsec.d/certs/client.cert.pem \ + -name "client.${VPN_DOMAIN}" \ + -certfile /etc/ipsec.d/cacerts/ca.cert.pem \ + -caname "StrongSwan CA" \ + -out /etc/ipsec.d/client.cert.p12 \ + -passout pass:${VPN_P12_PASSWORD} + +# gen mobileconfig for mac + +UUID1=$(uuidgen) +UUID2=$(uuidgen) +UUID3=$(uuidgen) +UUID4=$(uuidgen) +UUID5=$(uuidgen) +UUID6=$(uuidgen) + +cat > /etc/ipsec.d/client.mobileconfig <<_EOF_ + + + + + PayloadContent + + + Password + ${VPN_P12_PASSWORD} + PayloadCertificateFileName + client.cert.p12 + PayloadContent + +$(base64 /etc/ipsec.d/client.cert.p12) + + PayloadDescription + 添加 PKCS#12 格式的证书 + PayloadDisplayName + client.cert.p12 + PayloadIdentifier + com.apple.security.pkcs12.${UUID1} + PayloadType + com.apple.security.pkcs12 + PayloadUUID + ${UUID1} + PayloadVersion + 1 + + + PayloadCertificateFileName + ca.cer + PayloadContent + +$(base64 /etc/ipsec.d/cacerts/ca.cert.pem) + + PayloadDescription + 添加 CA 根证书 + PayloadDisplayName + StrongSwan CA + PayloadIdentifier + com.apple.security.root.${UUID2} + PayloadType + com.apple.security.root + PayloadUUID + ${UUID2} + PayloadVersion + 1 + + + IKEv2 + + AuthenticationMethod + Certificate + ChildSecurityAssociationParameters + + DiffieHellmanGroup + 2 + EncryptionAlgorithm + 3DES + IntegrityAlgorithm + SHA1-96 + LifeTimeInMinutes + 1440 + + DeadPeerDetectionRate + Medium + DisableMOBIKE + 0 + DisableRedirect + 0 + EnableCertificateRevocationCheck + 0 + EnablePFS + 0 + IKESecurityAssociationParameters + + DiffieHellmanGroup + 2 + EncryptionAlgorithm + 3DES + IntegrityAlgorithm + SHA1-96 + LifeTimeInMinutes + 1440 + + LocalIdentifier + client.${VPN_DOMAIN} + PayloadCertificateUUID + ${UUID1} + RemoteAddress + ${VPN_DOMAIN} + RemoteIdentifier + ${VPN_DOMAIN} + UseConfigurationAttributeInternalIPSubnet + 0 + + IPv4 + + OverridePrimary + 1 + + PayloadDescription + Configures VPN settings + PayloadDisplayName + VPN + PayloadIdentifier + com.apple.vpn.managed.${UUID4} + PayloadType + com.apple.vpn.managed + PayloadUUID + ${UUID4} + PayloadVersion + 1 + Proxies + + HTTPEnable + 0 + HTTPSEnable + 0 + + UserDefinedName + VPN (IKEv2) + VPNType + IKEv2 + + + PayloadCertificateFileName + server.cer + PayloadContent + +$(base64 /etc/ipsec.d/certs/server.cert.pem) + + PayloadDescription + 添加 PKCS#1 格式的证书 + PayloadDisplayName + ${VPN_DOMAIN} + PayloadIdentifier + com.apple.security.pkcs1.${UUID5} + PayloadType + com.apple.security.pkcs1 + PayloadUUID + ${UUID5} + PayloadVersion + 1 + + + PayloadDisplayName + VPN + PayloadIdentifier + com.github.vimagick.strongswan + PayloadRemovalDisallowed + + PayloadType + Configuration + PayloadUUID + ${UUID6} + PayloadVersion + 1 + + +_EOF_