我有一个 Digital Ocean droplet(类似于 Amazon EC2 实例),运行 Ubuntu Server 12.04.3 x64,并安装了 strongswan 5.1.1(从源代码构建)和 squid 3.4.2(也是从源代码构建)。
当然,strongswan VPN 和 squid 代理单独运行都很好,只是在测试期间进行了一些小的 iptables 规则更改。
我想要做的是能够从我的计算机/设备启动 VPN 连接,并让传出的 VPN 流量自动通过本地 squid 代理路由。
也就是说,流量流应该是这样的:
客户端 -> VPN -> 代理 -> 互联网
不幸的是,我似乎想不出一个好办法来让这种连接工作。一位朋友指出,iptables 中 NAT 表的输出链可能是我的解决方案,并建议使用如下规则:
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 3128
虽然从逻辑上讲,我认为这种做法是合理的,但实际上似乎并非如此。当我尝试在连接到 VPN 时加载内容时,我没有看到任何遵循规则的数据包(使用 iptables-save 命令定期检查传入/传出数据包计数)。
请注意,我不是 iptables 或 linux 方面的专家,所以如果我说的话(或我说的话)是愚蠢的/愚蠢的/显然是该死的问题,请忍耐一下。;)
我愿意听取任何关于如何解决这个问题的建议,但删除一个组件并不是解决办法。我需要 VPN 和代理都这样运行。更改任何一个组件的版本也不是理想的选择,尽管这样做更可行。
我提供了 ipsec.conf 和 squid.conf,以及我当前的 iptables 规则脚本。
PS 如果您注意到,有一些内容与使用 RADIUS 进行身份验证有关。 别担心。 它目前未被使用,并且不会对这个问题产生任何影响。
iptables 脚本:
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
export WAN=eth0
export vpnclients=10.100.0.0/255.255.0.0
# Allow access to our SSH server from the WAN
iptables -A INPUT -p TCP --dport ssh -i ${WAN} -j ACCEPT
# Add the rules for NAT
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3128
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 3128
iptables -t nat -A POSTROUTING -o ${WAN} -j MASQUERADE
iptables-save
ipsec.conf:
config setup
ca ipsec
cacert=ca.pem
auto=add
conn %default
ikelifetime=60m
keylife=20m
ike=aes256-sha1-modp1024!
esp=aes256-sha1!
leftcert=vpn-server.crt
leftauth=pubkey
rightsendcert=never
leftsendcert=always
eap_identity=%identity%
leftfirewall=yes
auto=add
conn ikev1
keyexchange=ikev1
rightauth=pubkey
rightauth2=xauth
rightsourceip=10.100.0.0/16
right=%any
rightid=%any
rightdns=8.8.8.8,8.8.4.4
leftsourceip=<my_server_ip>
leftsubnet=0.0.0.0/1,128.0.0.0/1,::/1,8000::/1
conn ikev2
keyexchange=ikev2
rightsourceip=10.100.0.0/16
right=%any
rightid=%any
rightauth=eap-radius
squid.conf:
#dummy name used
cache deny all
forwarded_for off
#for debugging, enable in production
strip_query_terms off
cache_effective_user proxy
cache_effective_group proxy
client_dst_passthru on
host_verify_strict off
http_port 3130 intercept
http_port 3128
https_port 3129 intercept ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/dev/squid.pem
always_direct allow all
ssl_bump server-first all
# the following two options are unsafe and not always necessary:
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
# Change these to your local DNS servers
dns_nameservers 8.8.8.8 8.8.4.4
coredump_dir /var/cache/squid
http_access allow all
http_reply_access allow all
答案1
我遇到了完全相同的问题,花了将近 1 天的时间才解决了这个问题。此解决方案适用于将来阅读此文的任何人。
目标:与我试图联系的 OP 相同
客户端 -> VPN -> 代理 -> 互联网
设置:Ubuntu 16.04
VPN:使用 xl2tpd 和 pptpd 的 L2TP,以及使用 strongswan 进行加密 VPN 设置和 Squid 代理服务器在同一台机器上。
用于向客户端分发 IP 的私有 IP 池:172.21.118.0/24
正如 OP 所期望的,您需要-j REDIRECT --to-port 3128
在某些 nat 表 (PREROUTING 或 OUTPUT) 上运行。
使用不同的表进行探测和记录,这是来自 172.21.118.0/24 的每个数据包所遵循的路径:
mangle PREROUTING -> nat PREROUTING -> mangle FORWARD -> filter FORWARD -> mangle POSTROUTING -> nat POSTROUTING
我通过对 iptables 数据包生命周期的一个很好的说明,理解了它的工作原理:
来源:http://64-bit.de/dokumentationen/netzwerk/e/002/DE-IPTABLES-HOWTO-3.html
事实证明,此设置不会在 OUTPUT 链上发送任何内容,因此重定向端口的唯一位置是 PREROUTING 链。
这解决方案简单来说就是:
iptables -t nat -I PREROUTING -i ppp0 -s 172.21.118.1/24 -j REDIRECT --to-ports 3128
另外,不要忘记将 SNAT 到您的公共 IP 以便访问互联网:
iptables -t nat -A POSTROUTING -j SNAT -s 172.21.118.2/24 --to-source ${IP} -o eth0
#Alternatively but slower:
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE