لماذا كل هذا ولماذا؟
كان لدينا: أبسط 10 تكوينات للخوادم على DigitalOcean ، وأجهزة iOS المحمولة ، وخادم لجمع الإحصائيات ، وليس لدينا خبرة في إعداد خوادم VPN ، ورغبة لا تُقهر في إنشاء خدمة VPN سريعة وموثوقة وسهلة الاستخدام ستستمتع بها استمتع. لا يعني هذا أن كل هذا كان ضروريًا للغاية ، ولكن إذا كنا قد بدأنا بالفعل ، فعلينا التعامل مع الأمر بجدية.
في هذه المقالة ، سأصف بإيجاز كيف اخترنا بروتوكول VPN ، وكيف قمنا بإعداد الخادم وكيف نظمنا مجموعة الإحصائيات من كل خادم VPN. لا تعتمد على تعليمات مفصلة خطوة بخطوة. في المقالة ، سأقدم مقتطفات من ملفات التكوين مع تعليقات موجزة.
أعتقد أنه في مجال تكنولوجيا المعلومات لن تجد شخصًا لا يعرف ما هي VPN ولماذا تحتاج إليها.
ولكن إذا كانت الأطروحة تشرح سبب احتياج الشخص الحديث لشبكة افتراضية خاصة ، فسيظهر شيء كهذا:
- إذا كان لديك أي موارد داخلية (خاصة) ، فيجب أن يكون الوصول إليها مقيدًا من الإنترنت العالمي.
- إذا كنت بحاجة إلى إنشاء اتصال آمن بين شبكتين.
- إذا كنت بحاجة إلى الوصول إلى الموارد التي ، لسبب أو لآخر ، غير متوفرة من بلدك (يتغير موقعك بالنسبة إلى عنوان IP الخاص بك).
والنقطة غير الواضحة تمامًا: يمكن أن تكون سرعة اتصال الإنترنت أعلى من خلال vpn ، لأن يمكن لمزود خدمة الإنترنت الخاص بك إرسال حركة المرور الخاصة بك على طول طريق أقصر ، مما يعني وجود طريق أفضل ، وبسبب هذا ، يمكنك الحصول على زيادة في السرعة. ولكن يمكن أن تعمل في الاتجاه المعاكس إذا اخترت موقع خادم غير جيد بالنسبة لك (المزيد عن ذلك لاحقًا).
VPN-
VPN- .
.
, :
- .
- .
+ , .
PPTP (Point-To-Point Tunneling Protocol)
VPN , Microsoft. - , . Microsoft L2TP SSTP PPTP.
, .
L2TP/IPSec
PPTP, . , -, .. .
L2TP/IPsec , . : , , VPN-.
.. , , , .
IKEv2/IPSec
Microsoft Cisco, (, OpenIKEv2, Openswan strongSwan).
Mobility and Multi-homing Protocol (MOBIKE), .
IKEv2 , WiFi .
IKEv2 .
, .. Mobility and Multi-homing Protocol .
OpenVPN
OpenVPN Technologies.
, .
OpenVPN . , TCP UPD, . VPN .
OpenVPN, , .
, , , - , .
Wireguard
VPN. IPSec OpenVPN, , , .
Unix , .. Unix. .
, , .
.
IKEv2/IPSe, :
- Mobility and Multi-homing Protocol (MOBIKE).
- .
- .
- .
.
VPN-
, , () ().
— , .. , ( ), .., , - .
- , digitalocean , 1 Gb 25 Gb .
, - VPN- .
:
- Docker + docker-compose.
- strongswan — IPSec .
- Let's Encrypt — .
- Radius — .
Docker , vpn-.
FROM alpine:latest # alpine-linux
...
# strongSwan Version
ARG SS_VERSION="https://download.strongswan.org/strongswan-5.8.2.tar.gz" # , .
...
COPY ./run.sh /run.sh
COPY ./adduser.sh /adduser.sh
COPY ./rmuser.sh /rmuser.sh
RUN chmod 755 /run.sh /adduser.sh /rmuser.sh
VOLUME ["/usr/local/etc/ipsec.secrets"]
EXPOSE 500:500/udp 4500:4500/udp
CMD ["/run.sh"]
adduser.sh, rmuser.sh .
adduser.sh
#!/bin/sh
VPN_USER="$1"
if [ -z "$VPN_USER" ]; then
echo "Usage: $0 username" >&2
echo "Example: $0 jordi" >&2
exit 1
fi
case "$VPN_USER" in
*[\\\"\']*)
echo "VPN credentials must not contain any of these characters: \\ \" '" >&2
exit 1
;;
esac
VPN_PASSWORD="$(openssl rand -base64 9)" #
HOST="$(printenv VPNHOST)"
echo "Password for user is: $VPN_PASSWORD"
echo $VPN_USER : EAP \"$VPN_PASSWORD\">> /usr/local/etc/ipsec.secrets # /usr/local/etc/ipsec.secrets
ipsec rereadsecrets
rmuser.sh
#!/bin/sh
VPN_USER="$1"
if [ -z "$VPN_USER" ]; then
echo "Usage: $0 username" >&2
echo "Example: $0 jordi" >&2
exit 1
fi
cp /usr/local/etc/ipsec.secrets /usr/local/etc/ipsec.secrets.bak
sed "/$VPN_USER :/d" /usr/local/etc/ipsec.secrets.bak > /usr/local/etc/ipsec.secrets # /usr/local/etc/ipsec.secrets
ipsec rereadsecrets
ipsec.secrets.
:
#!/bin/bash
VPNIPPOOL="10.15.1.0/24" # IP , VPN-.
LEFT_ID=${VPNHOST} # vpn-
sysctl net.ipv4.ip_forward=1
sysctl net.ipv6.conf.all.forwarding=1
sysctl net.ipv6.conf.eth0.proxy_ndp=1
if [ ! -z "$DNS_SERVERS" ] ; then # DNS , vpn .
DNS=$DNS_SERVERS
else
DNS="1.1.1.1,8.8.8.8"
fi
if [ ! -z "$SPEED_LIMIT" ] ; then # , "" , .
tc qdisc add dev eth0 handle 1: ingress
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip src 0.0.0.0/0 police rate ${SPEED_LIMIT}mbit burst 10k drop flowid :1
tc qdisc add dev eth0 root tbf rate ${SPEED_LIMIT}mbit latency 25ms burst 10k
fi
iptables -t nat -A POSTROUTING -s ${VPNIPPOOL} -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s ${VPNIPPOOL} -o eth0 -j MASQUERADE
iptables -L
#
if [[ ! -f "/usr/local/etc/ipsec.d/certs/fullchain.pem" && ! -f "/usr/local/etc/ipsec.d/private/privkey.pem" ]] ; then
certbot certonly --standalone --preferred-challenges http --agree-tos --no-eff-email --email ${LEEMAIL} -d ${VPNHOST}
cp /etc/letsencrypt/live/${VPNHOST}/fullchain.pem /usr/local/etc/ipsec.d/certs
cp /etc/letsencrypt/live/${VPNHOST}/privkey.pem /usr/local/etc/ipsec.d/private
cp /etc/letsencrypt/live/${VPNHOST}/chain.pem /usr/local/etc/ipsec.d/cacerts
fi
rm -f /var/run/starter.charon.pid
# ipsec
if [ -f "/usr/local/etc/ipsec.conf" ]; then
rm /usr/local/etc/ipsec.conf
cat >> /usr/local/etc/ipsec.conf <<EOF
config setup
charondebug="ike 1, knl 1, cfg 1"
uniqueids=never
conn ikev2-vpn
...
eap_identity=%identity
EOF
fi
if [ ! -f "/usr/local/etc/ipsec.secrets" ]; then
cat > /usr/local/etc/ipsec.secrets <<EOF
: RSA privkey.pem
EOF
fi
.....
EOF
fi
sysctl -p
ipsec start --nofork
, docker-compose:
version: '3'
services:
vpn:
build: .
container_name: ikev2-vpn-server
privileged: true
volumes:
- './data/certs/certs:/usr/local/etc/ipsec.d/certs'
- './data/certs/private:/usr/local/etc/ipsec.d/private'
- './data/certs/cacerts:/usr/local/etc/ipsec.d/cacerts'
- './data/etc/ipsec.d/ipsec.secrets:/usr/local/etc/ipsec.secrets'
env_file:
- .env
ports:
- '500:500/udp'
- '4500:4500/udp'
- '80:80'
depends_on:
- radius
links:
- radius
networks:
- backend
radius:
image: 'freeradius/freeradius-server:latest'
container_name: freeradius-server
volumes:
- './freeradius/clients.conf:/etc/raddb/clients.conf'
- './freeradius/mods-enabled/rest:/etc/raddb/mods-enabled/rest'
- './freeradius/sites-enabled/default:/etc/raddb/sites-enabled/default'
env_file:
- .env
command: radiusd -X
networks:
- backend
networks:
backend:
ipam:
config:
- subnet: 10.0.0.0/24
volume , .
, , Let's Encrypt.
.env , :
VPNHOST=vpn.vpn.com # vpn-
LEEMAIL=admin@admin.com # , Let's Encrypt
SPEED_LIMIT=20 # , mbit
DNS_SERVERS= # DNS
RADIUS_SERVER= # radius , radius
RADIUS_SERVER_SECRET= # , radius
REMOTE_SERVER= # endpoint, radius , .
docker-compose up -d, vpn-, radius ( ).
VPN-
, , . ipsec, , - , .
, , FreeRadius , ipsec .
FreeRadius , .
radius ipsec:
FreeRADIUS
if [[ ! -z "$RADIUS_SERVER" && ! -z "$RADIUS_SERVER_SECRET" ]]; then
rm /usr/local/etc/strongswan.d/charon/eap-radius.conf
cat >> /usr/local/etc/strongswan.d/charon/eap-radius.conf <<EOF
eap-radius {
accounting = yes # , ipsec /,
accounting_close_on_timeout = no
accounting_interval = 300 # radius .
close_all_on_timeout = no
load = yes
nas_identifier = $VPNHOST
# Section to specify multiple RADIUS servers.
servers {
primary {
address = $RADIUS_SERVER
secret = $RADIUS_SERVER_SECRET
auth_port = 1812 # default
acct_port = 1813 # default
}
}
}
endpoint, rest. /etc/raddb/mods-enabled/rest accounting, - :
accounting {
uri = "${..connect_uri}/vpn_sessions/%{Acct-Session-Id}-%{Acct-Unique-Session-ID}"
method = 'post'
tls = ${..tls}
body = json
data = '{ "username": "%{User-Name}", "nas_port": "%{NAS-Port}", "nas_ip_address": "%{NAS-IP-Address}", "framed_ip_address": "%{Framed-IP-Address}", "framed_ipv6_prefix": "%{Framed-IPv6-Prefix}", "nas_identifier": "%{NAS-Identifier}", "airespace_wlan_id": "%{Airespace-Wlan-Id}", "acct_session_id": "%{Acct-Session-Id}", "nas_port_type": "%{NAS-Port-Type}", "cisco_avpair": "%{Cisco-AVPair}", "acct_authentic": "%{Acct-Authentic}", "tunnel_type": "%{Tunnel-Type}", "tunnel_medium_type": "%{Tunnel-Medium-Type}", "tunnel_private_group_id": "%{Tunnel-Private-Group-Id}", "event_timestamp": "%{Event-Timestamp}", "acct_status_type": "%{Acct-Status-Type}", "acct_input_octets": "%{Acct-Input-Octets}", "acct_input_gigawords": "%{Acct-Input-Gigawords}", "acct_output_octets": "%{Acct-Output-Octets}", "acct_output_gigawords": "%{Acct-Output-Gigawords}", "acct_input_packets": "%{Acct-Input-Packets}", "acct_output_packets": "%{Acct-Output-Packets}", "acct_terminate_cause": "%{Acct-Terminate-Cause}", "acct_session_time": "%{Acct-Session-Time}", "acct_delay_time": "%{Acct-Delay-Time}", "calling_station_id": "%{Calling-Station-Id}", "called_station_id": "%{Called-Station-Id}"}'
}
.
VPN , , Apple , , , Let's Encrypt.
?
- radius , VPN.
- , VPN-.
VPN-?
- radius.
- .
- , .
- health-check .
?
من خلال التجربة والخطأ ، توصلنا إلى الخيار الموصوف في المقالة ، أولاً وقبل كل شيء التزمنا بمبدأ "اجعله أبسط" ، ولم نعيد اختراع دراجاتنا الخاصة واستخدمنا أدوات جاهزة مثل Docker و FreeRadius. نعم ، على الأرجح هناك مكان للتحسين وتشديد السياسات الأمنية والأتمتة. لكن خيارنا مثالي للاستخدام الشخصي وللاستخدام في الشركات الصغيرة إذا كنت بحاجة لتنظيم الوصول إلى المعلومات الخاصة (المغلقة).