通過埠對映突破防火牆

2021-09-05 17:34:06 字數 3009 閱讀 4950

在我做的專案中,經常遇到一種如下形式的網路結構。

出於安全的考慮,server處於防火牆之後,client無法直接訪問,只能通過telnet登陸到proxy server上訪問。在這種方式下,就無法利用cient上的各種強大的桌面工具(如資料庫客戶端等),只能通過telnet的命令列形式互動,確實有些不便。

我們可以通過埠對映解決這個問題,實現client到server的"直接訪問"。當client想訪問server時,只需要與proxy的某個埠建立連線,proxy監聽到這個連線後,建立乙個與server的連線(client的目標),同時提供這兩個連線的訊息傳輸管道。這樣,所有client發到proxy的訊息都傳送到了server上,server的訊息也傳送到了proxy上,從而實現了client到server的訪問。

由於連線的數目可能較多,並且proxy程式起著乙個訊息中轉的作用,因此程式本身需要較高的socket通訊效率,所有的操作都不能阻塞,否則嚴重影響其它的程序通訊,因此程式中的socket的連線,通訊方式都必須採用非同步操作。(多執行緒的方式如果連線的程序較多時則開銷太大)。

這種方式十分簡單有效,並且不需要對客戶端和伺服器端做任何修改。不足的地方有如下幾處:

proxy需要中轉所有的訊息,負荷較大。(不過處理目前的幾十個客戶端應用是綽綽有餘,並且目前的通訊瓶頸一般在internet上)

需要在proxy上建立埠監聽,並且所監聽的埠需要能被client直接訪問,這種情況的網路很多時候得不到滿足。(大多時候proxy只開放了幾個有限的埠,並無多餘的埠讓埠對映程式繫結)

本來我用c#寫了乙個,程式非常簡單,這裡就不拿出來了。

後來由於要把這個程式放到unix伺服器上長期執行,我就用c++重寫了一下,最初我是用socket api寫的,可程式的可讀性總是不盡人意,後來就改用了asio庫(asio 0.3.8 rc3,與早期的asio庫不相容),通過boost的asio,function,smart_ptr這幾個庫的運用,乙個c++版的埠對映程式便誕生了,精簡、高效、安全、跨平台,原來c++下的非同步socket也可以如此優雅。^_^

**如下:

#include

#include

#include

#include

#include

using boost::asio::ip::tcp;

using

namespace std;

class socket_client

: public boost::enable_shared_from_this

,public tcp::socket

public:

socket_client(boost::asio::io_service& io_service)

:tcp::socket(io_service)

};class socket_pipe

private:

void begin_read()

void end_read(const boost::system::error_code& error, size_t bytes_transferred)

void begin_write(int bytes_transferred)

void end_write(const boost::system::error_code& error)

void handle_error(const boost::system::error_code& error)

private:

socket_client& read_socket_;

socket_client& write_socket_;

socket_client::pointer read_;

socket_client::pointer write_;

enum ;

char data_[max_length];

};class async_listener

void begin_accept()

void end_accept(socket_client::pointer client, const boost::system::error_code& error)

void handle_error(const boost::system::error_code& error)

public:

accept_handler handle_accept;

private:

tcp::acceptor acceptor_;

boost::asio::io_service& io_service_;

};class port_map_server

void add_portmap(short port,tcp::endpoint& remote_endpoint)

void handle_accept(tcp::endpoint remote_endpoint,socket_client::pointer client)

void begin_connect(tcp::endpoint& remote_endpoint,socket_client::pointer socket_local)

void end_connect(const boost::system::error_code& error,socket_client::pointer socket_local,socket_client::pointer socket_remote)

else

}void handle_error(const boost::system::error_code& error)

private:

boost::asio::io_service& io_service_;

listlisteners;

};int main()

catch (std::exception& e)

return 0;

}

PIX防火牆配置埠對映。

使用pix防火牆或者asa防火牆配置埠對映時,需要配置2個步驟,1是配置埠對映,2是配置訪問控制列表。命令列舉 static inside,outside tcp inte ce 3389 10.0.0.13 3389 netmask 255.255.255.255 本條命令的含義是,當外網位址訪問...

思科ASA防火牆埠對映

需求將內網主機10.24.11.216的80埠對映到外網19909埠 asa5506x en password asa5506x conf t asa5506x config object network servermes216 port80 map asa5506x config network...

centos7防火牆埠對映

第一步 etc sysctl.conf中加入,然後sysctl p net.ipv4.ip forward 1 第二步 查詢是否開啟 no開啟 firewall cmd query masquerade 為no執行下面 firewall cmd add masquerade permanent 第三...