1. 透明代理.
虽然理论上透明代理可以对任何协议通用, 目前能实现的主要有:
DNS, sendmail relay, 和 HTTP.
1). DNS, sendmail relay服务本身与目标地址无关, 因此只需简
单的重定向一下端口.
ipchains -A input -d 0/0 53 -p tcp -j REDIRECT
ipchains -A input -d 0/0 53 -p udp -j REDIRECT
ipchains -A input -d 0/0 25 -p tcp -j REDIRECT
2). HTTP服务(也可以用于proxy服务). 有两种方法, 各有优缺点:
(1) 使用专用的转换进程httpd_transp.c, 这种方法是用专
用进程在定向后的端口上读取http请求, 用getsockname
获得目标地址, 再把连接转换到http proxy server上.
这种方法需要专用的进程处理, 消费系统资源, 但可以
使用其它机上的proxy, 而且兼容非HTTP/1.1请求.
(2) squid的透明代理功能. 此方法比较方便, 它使用HTTP
协议固有的功能,但不适合与不带host请求标志的连接.
(现在的标准浏览器都支持host标志). 还有, squid必须
装在firewall主机上. 方法:
ipchains -A input -d 0/0 80 -p tcp -j REDIRECT 3128
ipchains -A input -d 0/0 8080 -p tcp -j REDIRECT 3128
ipchains -A input -d 0/0 3128 -p tcp -j REDIRECT
在squid.conf里加上
httpd_accel_with_proxy on
httpd_accel virtual 80
后面两条ipchains用于定向对外的代理访问统统限制在本地
代理上, 由于squid本身不会通过getsockname来确定目标地址,
这种方法只能对80段口的http有效.
2. 端口重定向(服务定向,平衡).
目前linux核心支持两种途径实现服务重定向和服务平衡
1). IP portfw. 这是比较老的实行方法.对2.0.36的核心也实用.
ipmasqadm portfw -a -p tcp -L 1.1.1.1 80 -R 10.1.1.1 80
这里的1.1.1.1是firewall的地址, 防火墙内的10.1.1.1实际地址
在这里,可以对同一服务加多条规则. 实现服务平衡, 如:
ipmasqadm portfw -a -p tcp -L 1.1.1.1 80 -R 10.1.1.1 80 -P 1
ipmasqadm portfw -a -p tcp -L 1.1.1.1 80 -R 10.1.1.2 80 -P 2
这里, 该服务将以1:2分配到10.1.1.1/10.1.1.2两台机上
2). ip mark fw. 这是较新的一种方式, 比较灵活. 如果不是历史
原因, 建议使用这种方式
ipmasqadm mfw -A -m mark -r raddr [rport] [-p pref]
这里的-r相当于portfw的-R, -p相当于portfw的-P. 这里的rport
可以不声明, 表明使用源数据的端口. 如:
ipchains -A input -p tcp -d 0/0 137:139 -m 1 -j ACCEPT
ipchains -A input -p udp -d 0/0 137:139 -m 1 -j ACCEPT
ipchains -A input -p tcp -d 0/0 80 -m 1 -j ACCEPT
ipchains -A input -p tcp -d 0/0 81 -m 2 -j ACCEPT
ipmasqadm mfw -A -m 1 -r 10.1.1.1
ipmasqadm mfw -A -m 2 -r 10.1.1.2 80
这里, 把netbios, 和http(80)定向到10.1.1.1机上
而把81上的http定向到10.1.1.2机上.
3). 以上两种方式用于ftp时,都只能提供普通的port ftp方式,对于
passive的ftp方式, 要加载一个类似ip_masq_ftp的模块, 如果有
需要, 请注明核心版本, 与我联系. (由于此patch是历史之作,目
前我已经没有继续维护了).
4). 以此相关的autofw可以实现一些独占服务的访问(masq). 如SGI MediaBase MPEG Player.
ipmasqadm autofw -A -r udp 7000 7000 -c udp 6311
把firewall内player的设为proxy方式,端口7000即可
3. MAC/IP地址问题? 你能给出更清楚的需求吗? 现在就大概谈一下.
1) 获取本地IP地址和interface清单. 使用
struct ifreq ifr[32];
struct ifconf ifc;
int num, i;
int sock = socket( AF_INET, SOCK_DGRAM, 0 );
ifc.ifc_len = sizeof ifr;
ifc.ifc_req = ifr;
num = ioctl( sock, SIOCGIFCONF, &ifc );
for( i = 0; i < num/sizeof(struct ifreq); i++){
/* process each ifr[i] */
}
2) 获取interface的IP/MAC地址.
struct ifreq ifr;
int sock = socket( AF_INET, SOCK_DGRAM, 0 );
ioctl( sock, SIOCGIFHWADDR, &ifr );
此外, 还有SIOCGIFFLAGS, SIOCGIFDSTADDR, SIOCGIFBRDADDR...
3) 读取arp cache的内容. 直接打开/proc/net/arp文件.
或者通过ioctl/SIOCGARP来实现.
相关链接: http://support.turbolinux.com.cn/article.php3?sid=20000317171343&mode=flat