Tôi có một VPS chạy CentOS 7 mà tôi kết nối với SSH. Tôi muốn chạy ứng dụng khách OpenVPN trên VPS để lưu lượng truy cập internet được định tuyến qua VPN, nhưng vẫn cho phép tôi kết nối với máy chủ qua SSH. Khi tôi khởi động OpenVPN, phiên SSH của tôi bị ngắt kết nối và tôi không thể kết nối với VPS của mình được nữa. Làm cách nào để định cấu hình VPS để cho phép các kết nối SSH (cổng 22) đến được mở trên IP thực của VPS (104.167.102.77), nhưng vẫn định tuyến lưu lượng đi (như từ trình duyệt web trên VPS) thông qua VPN?

Dịch vụ OpenVPN tôi sử dụng là PrivateInternetAccess và tệp config.ovpn ví dụ là:

client
dev tun
proto udp
remote nl.privateinternetaccess.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
tls-client
remote-cert-tls server
auth-user-pass
comp-lzo
verb 1
reneg-sec 0
crl-verify crl.pem

Trình bổ sung ip của VPS:

1: lo:  mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:be:16:f7 brd ff:ff:ff:ff:ff:ff
    inet 104.167.102.77/24 brd 104.167.102.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:febe:16f7/64 scope link
       valid_lft forever preferred_lft forever
4: tun0:  mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 100
    link/none
    inet 10.172.1.6 peer 10.172.1.5/32 scope global tun0
       valid_lft forever preferred_lft forever

Tuyến đường ip của VPS:

0.0.0.0/1 via 10.172.1.5 dev tun0
default via 104.167.102.1 dev ens33  proto static  metric 1024
10.172.1.1 via 10.172.1.5 dev tun0
10.172.1.5 dev tun0  proto kernel  scope link  src 10.172.1.6
104.167.102.0/24 dev ens33  proto kernel  scope link  src 104.167.102.77
109.201.154.177 via 104.167.102.1 dev ens33
128.0.0.0/1 via 10.172.1.5 dev tun0
answer

Tôi đang gặp sự cố tương tự với vấn đề này và đã cố gắng khắc phục được mô tả trong bài đăng trên diễn đàn này .

Ý tưởng là hiện tại khi bạn kết nối với địa chỉ IP công cộng của mình, các gói trả về đang được định tuyến qua VPN. Bạn cần buộc các gói này được định tuyến qua giao diện công khai của bạn.

Các lệnh định tuyến này hy vọng sẽ thực hiện thủ thuật:

ip rule add from x.x.x.x table 128

ip route add table 128 to y.y.y.y/y dev ethX

ip route add table 128 default via z.z.z.z

Trong đó xxxx là IP công cộng của bạn, yyyy / y phải là mạng con của địa chỉ IP công cộng của bạn, ethX phải là giao diện Ethernet công cộng của bạn và zzzz phải là cổng mặc định.

Lưu ý rằng điều này không hiệu quả với tôi (sử dụng Debian và PrivateInternetAccess) nhưng có thể giúp ích cho bạn.

Dựa trên câu trả lời @MrK, tôi đã viết một số mã đơn giản ở đây để giúp thực hiện công việc nhanh hơn, do đó bạn không phải kiểm tra giao diện / IP:

ip rule add from $(ip route get 1 | grep -Po '(?<=src )(\S+)') table 128
ip route add table 128 to $(ip route get 1 | grep -Po '(?<=src )(\S+)')/32 dev $(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)')
ip route add table 128 default via $(ip -4 route ls | grep default | grep -Po '(?<=via )(\S+)')

Tôi đã thử tập lệnh này trên 4 VPS của mình và nó hoạt động hoàn hảo.

Điều này có thể hơi muộn, nhưng ...

Vấn đề là cổng mặc định bị OpenVPN thay đổi và điều đó phá vỡ kết nối SSH hiện tại của bạn trừ khi bạn thiết lập các tuyến thích hợp trước khi khởi động OpenVPN.

Những gì sau đây phù hợp với tôi. Nó sử dụng iptables và ip (iproute2). Dưới đây, giả định rằng giao diện cổng mặc định trước khi OpenVPN được khởi động là "eth0". Ý tưởng là để đảm bảo rằng khi một kết nối đến eth0 được thực hiện, ngay cả khi eth0 không phải là giao diện cổng mặc định nữa, các gói phản hồi cho kết nối sẽ quay trở lại trên eth0 một lần nữa.

Bạn có thể sử dụng cùng một số cho dấu kết nối, dấu tường lửa và bảng định tuyến. Tôi đã sử dụng các con số riêng biệt để làm cho sự khác biệt giữa chúng rõ ràng hơn.

# set "connection" mark of connection from eth0 when first packet of connection arrives
sudo iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234

# set "firewall" mark for response packets in connection with our connection mark
sudo iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321

# our routing table with eth0 as gateway interface
sudo ip route add default dev eth0 table 3412

# route packets with our firewall mark using our routing table
sudo ip rule add fwmark 4321 table 3412

===

CẬP NHẬT:

Phần trên hoạt động tốt đối với tôi trên Debian Jessie. Nhưng trên một hệ thống Wheezy cũ hơn, tôi vừa thấy rằng tôi cần thêm "qua" vào mục nhập bảng định tuyến:

# our routing table with eth0 as gateway interface
sudo ip route add default dev eth0 via 12.345.67.89 table 3412

Ở đó "12.345.67.89" phải là cổng không phải VPN ban đầu.

hmm âm thanh như ip con chồng chéo lên nhau .... mà không biết thêm về lược đồ ip của bạn, ngoài ip công cộng cho kết thúc vpn của bạn là nl.privateinternetaccess.com, không thể nói chắc chắn.

vì vậy, ví dụ: nếu mạng con từ xa ở phía bên kia của nl.privateinternetaccess.com là 10.32.43.0/24 và phiên bản của bạn nằm trong vpc aws có mạng con là 10.32.44.0/24. nhưng ứng dụng ssh nguồn của bạn sống trên 10.32.43.0/24 (phía bạn là aws vpc), nó sẽ không hoạt động, vì lưu lượng ssh trả về sẽ bị đẩy nhầm qua vpn sang Hà Lan.

cung cấp đầy đủ thông tin ip / subnet để được trợ giúp thêm về việc này.

...

ok, vậy ... có vẻ như tuyến đường mặc định của bạn nằm trong đường hầm, sau khi bạn kết nối với nl:

0.0.0.0/1 via 10.172.1.5 dev tun0

vì vậy bạn có thể thay đổi điều đó sau khi kết nối. rất nhiều lần máy chủ vpn cung cấp cho bạn các tuyến đường không có thật. đặc biệt tại quân đoàn cẩu thả. trong trường hợp này, họ đang đẩy một tuyến đường mặc định cho bạn để tất cả lưu lượng truy cập từ hộp vps sẽ chuyển sang nl. thay đổi tuyến đường mặc định thành 104.167.102.x hoặc bất kỳ cổng mạng con nào của nhà cung cấp vps ur.

Khi bạn mở VPN lên, cổng mặc định của bạn sẽ được thay thế. Điều này có nghĩa là bất kỳ lưu lượng nào được tạo từ hoặc được định tuyến qua hộp của bạn sẽ được chuyển tiếp đến cổng VPN.

Một giải pháp đơn giản là lọc tất cả lưu lượng mà bạn không muốn định tuyến thông qua VPN và làm điều gì đó khác với nó. Một khả năng là nhận lưu lượng truy cập được tạo từ hộp của bạn với địa chỉ nguồn cục bộ của bạn và định tuyến nó qua cổng cục bộ của bạn. Điều này cho phép các dịch vụ như SSH hoạt động bình thường.

Chúng tôi sẽ làm điều đó ở đây. Trước tiên, hãy tạo một bảng định tuyến mới và thêm một tuyến đường mặc định để định tuyến mọi thứ qua cổng cục bộ của bạn:

# <table> is any number between 2 and 252.
# Check /etc/iproute2/rt_tables for more info.
ip route add default via <gateway> table <table>
ip route add <lan-addr> dev <device> table <table>

Tiếp theo, tạo một quy tắc lọc gói mới đánh dấu tất cả lưu lượng truy cập rời khỏi hộp của bạn từ một địa chỉ nguồn nhất định với một số định danh.

# <mark> is any number.
iptables -tmangle -AOUTPUT -s<local-addr> -jMARK --set-mark <mark>

Cuối cùng, tạo chính sách định tuyến chọn tất cả lưu lượng được đánh dấu nói trên và định tuyến nó bằng cách sử dụng bảng đã tạo ở trên.

ip rule add fwmark <mark> table <table>

Một lần nữa, các giá trị của <mark><table>là số nhận dạng tùy ý do bạn lựa chọn.

Đối với tôi khi tự chạy máy chủ OpenVPN trong pfSense đã bỏ chọn cài đặt "Buộc tất cả lưu lượng IPv4 do máy khách tạo qua đường hầm."

Tôi đã gặp sự cố tương tự trên phiên bản AWS (Máy khách VPN) được kết nối với máy chủ OpenVPN tại chỗ mà tôi không thể truy cập nó trừ khi tôi được kết nối với cùng một máy chủ VPN hoặc mạng tại chỗ. Giải pháp chỉ là thêm một tuyến đường từ địa chỉ IP công cộng của máy cục bộ vào cổng phiên bản AWS

ip route add xx.xxx.xx.xx via 172.xx.xx.1 dev eth0

và tôi có thể lặp lại điều này cho bất kỳ người dùng bên ngoài nào cần có quyền truy cập vào phiên bản AWS vì nó chỉ cần được chia sẻ với một số ít người dùng bên ngoài.

Mở rộng trên https://serverfault.com/a/660106/577384https://serverfault.com/a/793700/577384 . Để điều này hoạt động bình thường với các dịch vụ docker công khai, tôi cũng phải làm ip -4 rule add to 172.0.0.0/8. Để ngăn các gói đi đến localhost (các dịch vụ của docker) không được định tuyến qua eth0. Đảm bảo rằng quy tắc này được đặt trước quy tắc 'bảng'.

Tôi cũng có quy tắc sau trước phần còn lại của các quy tắc iptable, cho các thiết bị mạng LAN nói chung iptables -A PREROUTING -t mangle -s 192.168.0.0/16 -j ACCEPT -m comment --comment "Skip special route for LAN".

(Tôi nhấn mạnh rằng tôi sẽ cần một cái gì đó tương tự cho IPv6, nhưng tôi chưa có trình chạy docker trong IPv6)