Setup IKEv2 On Demand VPN on iOS 8 and IKEv2, IKEv1 Cisco IPSec VPN with Strongswan

First, install Strongswan on Ubuntu.
首先,在Ubuntu上安装Strongswan。
sudo apt-get install strongswan strongswan-plugin-eap-mschapv2 strongswan-plugin-xauth-generic
[info]If you want to compile from source, you need to add this to your configure command:
如果你想从源码编译,请确保你的configure指令包含以下参数:
./configure --prefix=/usr --sysconfdir=/etc --enable-eap-mschapv2 --enable-eap-identity --enable-eap-peap --enable-openssl --enable-md4
https://lists.strongswan.org/pipermail/users/2012-November/003975.html
You can use these command to install Strongswan from source:
你可以用这些命令来从源码安装Strongswan:
apt-get install build-essential libssl-dev libgmp-dev
wget http://download.strongswan.org/strongswan-5.2.0.tar.bz2
tar xjvf strongswan-5.2.0.tar.bz2; cd strongswan-5.2.0
./configure --prefix=/usr --sysconfdir=/etc --enable-eap-mschapv2 --enable-eap-identity --enable-eap-peap --enable-openssl --enable-md4
make & make install
[/info]
apt-get also suggest some packages, some of them are useful if you want to connect your strongswan with Radius or something else.
apt-get会列出一些推荐的包,如果你需要扩展Strongswan的功能比如连接Radius、mysql之类的后端数据库,那你可能会需要安装这些插件。
Suggested packages:
strongswan-tnc-imcvs network-manager-strongswan strongswan-plugin-agent
strongswan-plugin-certexpire strongswan-plugin-coupling
strongswan-plugin-curl strongswan-plugin-dnscert strongswan-plugin-dnskey
strongswan-plugin-duplicheck strongswan-plugin-error-notify
strongswan-plugin-ipseckey strongswan-plugin-ldap strongswan-plugin-led
strongswan-plugin-lookip strongswan-plugin-ntru strongswan-plugin-pkcs11
strongswan-plugin-radattr strongswan-plugin-sql strongswan-plugin-soup
strongswan-plugin-unity strongswan-plugin-whitelist strongswan-tnc-client
strongswan-tnc-server

Now, use
现在使用

ipsec version

to check if ipsec installd successful
命令来检查ipsec的安装是否成功

Then, open /etc/ipsec.secrets. If this file not exists, create a new one.
然后编辑/etc/ipsec.secrets文件。如果不存在就创建一个。
Sudo vim /etc/ipsec.secrets

Write this:
添加如下内容:
: RSA vpnHostKey.pem
: PSK yourpskhere
user1 : EAP "topsecretpassword"
user1 : XAUTH "topsecretpassword"
user2 : XAUTH "evenmoretopsecretpassword"

For security reasons, please change the password in the file, not just use the one I gave.
为了安全起见,请不要使用文中提供的账号密码,使用自定义的账号密码。

By the way, there is a command to reload this file without restart IPSec:
顺便一说,有一个命令可以热加载这个文件:
sudo ipsec rereadsecrets

You can use it to flush the secrets after you modify this file.
在修改了这个文件之后可以直接使用这个命令刷新新的用户密码。

Then modify system config to fit ip forward:
接下来修改系统配置以开启IP包转发:

sudo vim /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

Then set up iptables to enable forward. If you skip this step or make some mistakes, your VPN may can only connect to the server it self or you may lose SSH connection after you start the iptables.
接下来修改iptables的配置来启用转发。如果你跳过了这一步,你的VPN就只能访问服务器本身;如果你在这一步出错,可能会导致你的SSH链接丢失,然后连不上VPN。
[info]If you have any question, please contact me. wzxjohn#gmail
如果你在设置过程中遇到了困难,欢迎联系我。wzxjohn#gmail[/info]
[info]If you use Debian, you don’t need to use ufw. Just use iptables it self.DO NOT INSTALL ufw!
如果你使用Debian系统,你不需要使用ufw。用直接用iptables即可。不要安装ufw
Just create iptables.up.rules and put “iptables-restore < /etc/iptables.up.rules" in /etc/rc.local. 创建iptables.up.rules文件并把"iptables-restore < /etc/iptables.up.rules" 写入 /etc/rc.local 文件即可。[/info] sudo vim /etc/iptables.up.rules If the file is not exists, create a new one. 编辑/etc/iptables.up.rules文件。如果不存在就创建一个。 https://gist.github.com/wzxjohn/3d1f275b1a36b39475d8 Then put 然后将下面两行 iptables-restore < /etc/iptables.up.rules ufw reload
in /etc/rc.local
写入/etc/rc.local

Now it’s better to restart your VPS now.
现在最好重启一下你的VPS来看看设置是否正确。

If you don’t want to restart, just type
如果你不想重启,可以使用如下命令:
ufw enable
ufw reload

to make sure the iptables rules are working
来确保iptables规则正确加载

Now about ipsec config
接下来是ipsec配置。

This is my config file:
这是我的ipsec配置文件:

I may add some comments later.
之后我可能会添加一些注视。

This config file has 4 part, defined 3 kinds of VPN: IKEv2, IKEv2 with EAP, CiscoIPSec(IKEv1).
这个配置文件包含了4个部分,定义了三种VPN:IKEv2, IKEv2 with EAP, CiscoIPSec(IKEv1)

Save the config file and type ipsec restart in console.
保存配置文件并执行ipsec restart

Then, about the server cert, in the ipsec.config, we defined the file name server.pem.
接下来是关于服务端证书。在ipsec.config文件里,我们定义了证书文件的名字server.pem。

[info]You can also use Wildcard SSL certs, but you should modify the leftid in the ipsec.conf to @*.your.domain
你也可以使用通配符SSL证书,但是你需要修改ipsec.conf中的leftid为@*.your.domain

And the server address must end in your.domain, which means it can be a.your.domain, b.your.domain, c.your.domain etc.
并且服务器域名必须以your.domain结尾,比如a.your.domain, b.your.domain, c.your.domain等等。

So you can use exactly same config file and cert on all of your servers. All you should do is give them different sub domain names.
所以你可以在你的所有服务器上使用完全相同的配置。你只需要给它们分配不同的子域名即可。
[/info]

[warning]The Common Name in the cert must match the leftid and the real server domain name.
证书中所写的Common Name必须与配置中的leftid和真实的服务器域名匹配。

Which means if you want to access your server by a.your.domain, the Common Name in the cert should exactly be a.your.domain or *.your.domain. Any other string is not accept.
也就是说,如果你想用a.your.domain来访问你的服务器,那证书中的Common Name就必须是a.your.domain或者*.your.domain。其余字符都不可以。

And the left id in ipsec.conf should be @a.your.domain or @*.your.domain.
并且ipsec.conf中的leftid必须是@a.your.domain 或者 @*.your.domain

If not, it will cause connection error because of cert don’t match.
如果有任何不满足,都会导致因证书不匹配的连接失败。
[/warning]

[info]I haven’t try about no domain server, according to the documents about config, you may use self-certificate cert and change the leftid in ipsec.conf, and need to install CA cert on your device.
目前没有尝试过纯使用IP的服务端,按照配置文件的写法应该是需要自签名证书和修改leftid,并且需要将自签名CA安装到手机上。

Update 10/10/2014:
Accroding to Justin’s test, if you want to use IP as the server address, you need to follow these three suggestions:
根据Justin的测试,如果你想使用纯IP的服务器,你需要遵守这三条建议:

1.When creating server cert, you need to use:
当创建服务端证书的时候,你需要使用:
--dn "C=CH, O=strongSwan, CN=Server-IP-Address" \
--san Server-IP-Address \

instead of Server Domain name.
而不是服务器的域名

2.About ipsec.conf,the leftid in it should be exactly the server’s ip address, like:
在ipsec.conf文件中,leftid必须是服务器的IP地址,比如:
leftid = 123.456.789.123

3.About the mobileconfig file, the RemoteIdentifier should be exactly the server’s ip address, like:
在配置文件中,远程标识符必须是服务器的IP地址,如:
RemoteIdentifier
123.456.789.123
[/info]

Just rename your domain cert to the name you set and put it in /etc/ipsec.d/certs/, it’s server.pem in this case.
把你给你的域名申请的证书重命名成配置文件中的名称然后放进/etc/ipsec.d/certs/文件夹,这里是server.pem。

For private key, the file name is defined in ipsec.secrets, as vpnHostKey.pem in this case.
关于证书对应的私钥,ipsec.secrets文件中定义了其文件名,这里是vpnHostKey.pem。

Just rename your own private key to this name and put it in /etc/ipsec.d/private/.
把你的域名证书对应的私钥重命名成配置文件中的名称然后放入/etc/ipsec.d/private/。

[info]Here server.pem is what we call ssl.crt(SSLCertificateFile) in setting up Apache SSL site.
这里的server.pem是我们在配置Apache的SSL时通常所说的ssl.crt(SSLCertificateFile)。

The vpnHostKey.pem is what we call ssl.key(SSLCertificateKeyFile) or private key for cert.
vpnHostKey.pe是我们通常所说的ssl.key(SSLCertificateKeyFile)或者叫证书私钥。
[/info]

Then execute ipsec restart than every thing you should do on server side is done.
接下来执行ipsec restart,然后服务端的所有配置就完成了。

Now for mobileconfig file for iOS 8.
然后是给iOS 8使用的配置文件。

This is my mobile config profile:
这是我在使用的配置文件:

Please modify the username, password, server address in this profile and than install it on your device. You can use import function in Apple Configurator or just modify it use any text editor.
在使用前请修改用户名,密码,服务器地址,然后把配置文件安装到设备上。你可以使用Apple Configurator的导入功能导入这个配置文件然后修改,也可以直接用任何文本编辑器修改。

[info]Additional information about signed mobile config file. You can use this command to sign your mobileconfig file:
关于mobileconfig文件的签名,你可以用这个命令来给你的配置文件签名:
[/info]

openssl smime \
-sign \
-signer ssl.crt \
-inkey ssl.key \
-certfile ca.pem \
-nodetach \
-outform der \
-in MyProfile.mobileconfig \
-out Myprofile_signed.mobileconfig

[info]ssl.crt can be your domain cert or E-mail cert. ssl.key is the private key of the cert. ca.pem may need to let the device trust your own cert. In file and out file MUST be different!
ssl.crt可以是你域名的证书或者是E-mail证书。ssl.key是对应的私钥。有些设备可能需要ca.pem来进行证书信任的验证。输入和输出文件必须不同名!

About self-signed cert, please read this article:
自签名证书参考文章:
https://www.zeitgeist.se/2013/11/22/strongswan-howto-create-your-own-vpn/
[/info]

[info]If you want to see more things in IPSec’s log, you can add this in to your ipsec.conf:
如果你想在你的IPSec日志中看到更详细的信息,你可以在ipsec.conf文件中加入这句话:
charondebug="cfg 2, dmn 2, ike 2, net 2"
then the config file will look like this:
然后配置文件会变成这样:
config setup
charondebug = "cfg 2, dmn 2, ike 2, net 2"
uniqueids = no

Now restart ipsec and you will see more things in /var/log/syslog(or /var/log/daemon, /var/log/messages) about your ipsec vpn services.
现在重启ipsec服务,然后你就能在/var/log/syslog(或者 /var/log/daemon, /var/log/messages)中看到关于你的VPN服务的更多信息。

About charondebug, you can find official document hers:
关于charondebug参数,你可以在这里找到官方的文档:
https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration

Normally, we just need level 2 log. Level 3 and above write some RAW date in hex which we may not need.
一般情况下我们只需要Level 2的日志。Level 3以上的日志包含一些我们可能不太需要的原始包信息。

After debug your vpn server, you may delete the charondebug line, or your log file’s size will grow very fast.
在你调试完你的VPN服务器之后,你最好删除charondebug这一行,不然你的日志文件会迅速增大。

Levels and Subsystems/Groups
The IKE daemon knows different numerical levels of logging, ranging from -1 to 4:

-1: Absolutely silent
0: Very basic auditing logs, (e.g. SA up/SA down)
1: Generic control flow with errors, a good default to see whats going on
2: More detailed debugging control flow
3: Including RAW data dumps in hex
4: Also include sensitive material in dumps, e.g. keys
Each logging message also has a source from which subsystem in the daemon the log came from:

app: applications other than daemons
asn: Low-level encoding/decoding (ASN.1, X.509 etc.)
cfg: Configuration management and plugins
chd: CHILD_SA/IPsec SA
dmn: Main daemon setup/cleanup/signal handling
enc: Packet encoding/decoding encryption/decryption operations
esp: libipsec library messages
ike: IKE_SA/ISAKMP SA
imc: Integrity Measurement Collector
imv: Integrity Measurement Verifier
job: Jobs queuing/processing and thread pool management
knl: IPsec/Networking kernel interface
lib: libstrongwan library messages
mgr: IKE_SA manager, handling synchronization for IKE_SA access
net: IKE network communication
pts: Platform Trust Service
tls: libtls library messages
tnc: Trusted Network Connect

[/info]

PS命令的STAT列含义

通常,ps命令的输出结果是这样的:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  27176  2960 ?        Ss   Sep20   0:02 /sbin/init
root         2  0.0  0.0      0     0 ?        S    Sep20   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    Sep20  13:05 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   Sep20   0:00 [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S<   Sep20   0:00 [kworker/u:0H]
root         8  0.0  0.0      0     0 ?        S    Sep20   2:16 [migration/0]
root         9  0.0  0.0      0     0 ?        S    Sep20   0:00 [rcu_bh]
root        10  0.0  0.0      0     0 ?        S    Sep20  20:08 [rcu_sched]
root        11  0.0  0.0      0     0 ?        S    Sep20   0:07 [watchdog/0]
root        12  0.0  0.0      0     0 ?        S    Sep20   0:05 [watchdog/1]
root        13  0.0  0.0      0     0 ?        S    Sep20   2:21 [ksoftirqd/1]
root        14  0.0  0.0      0     0 ?        S    Sep20   1:00 [migration/1]

其中STAT列的各个标识的含义如下:
PROCESS STATE CODES
Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process:
D uninterruptible sleep (usually IO)
R running or runnable (on run queue)
S interruptible sleep (waiting for an event to complete)
T stopped, either by a job control signal or because it is being traced.
W paging (not valid since the 2.6.xx kernel)
X dead (should never be seen)
Z defunct ("zombie") process, terminated but not reaped by its parent.

For BSD formats and when the stat keyword is used, additional characters may be displayed:
< high-priority (not nice to other users) N low-priority (nice to other users) L has pages locked into memory (for real-time and custom IO) s is a session leader l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do) + is in the foreground process group.

Secure Network (ssh端口映射)

实战 SSH 端口转发

https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/

SSH的端口转发:本地转发Local Forward和远程转发Remote Forward

关于使用ssh portforwarding来进行翻墙的操作,网络上已经有很多很好的文章,我在这里只是画两个图解释一下。

首先要记住一件事情就是:

SSH 端口转发自然需要 SSH 连接,而 SSH 连接是有方向的,从 SSH Client 到 SSH Server 。

而我们所要访问的应用也是有方向的,应用连接的方向也是从应用的 Client 端连接到应用的 Server 端。比如需要我们要访问Internet上的Web站点时,Http应用的方向就是从我们自己这台主机(Client)到远处的Web Server。

如果SSH连接和应用的连接这两个连接的方向一致,那我们就说它是本地转发。

ssh -L :: 
Chapter 8 Secure Network (ssh端口映射) - linux-ul - unix-EA

如果SSH连接和应用的连接这两个连接的方向不同,那我们就说它是远程转发。

ssh -R :: 
Chapter 8 Secure Network (ssh端口映射) - linux-ul - unix-EA

本地转发在本地这台机器上监听一个端口,然后所有访问这个端口的数据都会通过ssh 隧道传输到远端的对应端口上,下面是例子。

本地端口转发绑定的是 lookback 接口,这意味着只有 localhost 或者 127.0.0.1 才能使用本机的端口转发 , 其他机器发起的连接只会得到“ connection refused. ”。要想让其他机器也能共享这个隧道来转发的话需要在配置文件中使用GatewayPorts 关键字,或者直接命令行下使用”-g”参数。

另外本地转发命令中的 可以是不同的主机。

Chapter 8 Secure Network (ssh端口映射) - linux-ul - unix-EA

远程转发与本地转发正好相反,打开ssh隧道以后,在远端服务器监听一个端口,所有访问远端服务器指定端口都会通过隧道传输到本地的对应端口上,下面是例子。

Chapter 8 Secure Network (ssh端口映射) - linux-ul - unix-EA

这里是一篇很好的介绍SSH PortForwarding的文章http://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/

可以将远端服务器一个端口remote_port绑定到本地端口port,其中-C是进行数据压缩,-f是后台操作,只有当提示用户名密码的时候才转向前台。-N是不执行远端命令,在只是端口转发时这条命令很有用处。-g 是允许远端主机连接本地转发端口。-R表明是将远端主机端口映射到本地端口。如果是-L,则是将本地端口映射到远端主机端口。

ssh的三个强大的端口转发命令:

转发到远端:ssh -C -f -N -g -L 本地端口:目标IP:目标端口 用户名@目标IP

转发到本地:ssh -C -f -N -g –R 本地端口:目标IP:目标端口 用户名@目标IP

ssh -C -f -N -g -D listen_port user@Tunnel_Host

-C:压缩数据传输。

-f :后台认证用户/密码,通常和-N连用,不用登录到远程主机。

-N :不执行脚本或命令,通常与-f连用。

-g :在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接。

-L 本地端口:目标IP:目标端口

将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport

-R本地端口:目标IP:目标端口

将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport

-p :被登录的ssd服务器的sshd服务端口。

-D port

指定一个本地机器 “动态的’’ 应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.

应用举例

1.将发往本机的80端口访问转发到174.139.9.66的8080端口

ssh -C -f -N -g -L 80:174.139.9.66:8080     master@174.139.9.66

2.将发往174.139.9.66的8080访问转发到本机的80端口

ssh -C -f -N -g -R 80:174.139.9.66:8080            master@174.139.9.66

-N – 不使用Shell窗口,纯做转发的时候用,如果你在映射完成后继续在服务器上输入命令,去掉这个参数即可

例子A:我们想远程管理服务器上的MySQL,那么使用下面命令

ssh -L 3306:127.0.0.1:3306   user@emlog-vps    -N 

运行这个命令之后,ssh将会自动将服务器的3306映射到本机的3306端口,我们就可以使用任意MySQL客户端连接 localhost:3306即可访问到服务器上的MySQL了。

例子B:一次同时映射多个端口

ssh -L 8888:www.host.com:80 -L 110:mail.host.com:110 -L    25:mail.host.com:25 user@host -N

这个命令将自动把服务器的80,110,25端口映射到本机的8888,110和25端口 以上命令在ubuntu 9.10 上测试通过…

 

端口映射让外部用户同时访问内部多个应用

如下图所示,这是企业部署NAT服务器的典型案例。如果现在企业内部有两台服务器,分别为WEB服务器(192.168.0.3)与ERP服务器(192.168.0.2)。现在企业想让出差在外的员工,也可以通过互联网访问企业内部的这两个应用,该如何设计呢?

Chapter 8 Secure Network (ssh端口映射) - linux-ul - unix-EA

  一、基于端口访问的一般原理。

在讲解NAT服务器的具体端口映射配置之前,笔者觉得读者有必要先了解一下基于端口访问的一般原理。这有利于读者了解下面的具体配置。下面笔者以员工访问WEB服务器为例,谈谈基于端口访问的基本步骤。假设现在某个用户需要访问WEB服务器,则客户端的浏览器(假设采用的端口为3000)与WEB服务器(假设采用的端口为80)是如何来进行通信的呢?

第一步:发起连接请求。当用户需要查看公司网页时,用户所用的主机会像WEB服务器发送请求。在这个发起请求的过程中,会有一些参数传递。如在发送请求的过程中,用户所用的主机需要知道WEB服务器的IP地址、所采用的协议(HTTP)等。另外就是两个端口信息。一是用户浏览器所用的端口,即为3000。二是WEB服务器网站所用的端口(如果采用的是HTTP服务,则默认为80端口)。

第二步:WEB服务器转发请求。当服务器接受到这个请求后,会分析数据包。他经过分析包发现,这个请求是要求端口为80的应用软件来负责的。服务器确定了负责人之后,就会把这个请求转发给具体的负责人,即WEB应用服务器来处理。

第三步:服务器会把从WEB应用服务那边反馈回来的网页传送给用户所用的计算机。在传送的时候,其也会制定要把这个网页给你的那个3000端口(浏览器)对应的应用软件。

第四步:用户的计算机收到数据包之后,也会对这个数据包进行分析,来判断需要把这个数据包转发给哪个端口(应用服务)。分析后发现是转交给3000端口的,就会把这个数据包转发给浏览器。

二、基于端口映射的NAT服务器配置。

其实基于端口映射的NAT服务器其工作原理就跟上面这个基于端口访问的工作过程类似。只是这里的NAT服务器就相当于用户主机,而用户相当于内部的服务器。由于用户需要通过外网访问企业内部应用的话,通常情况下要求内网服务器也要求有合法的外网IP。只有私网IP地址的服务器是无法直接跟外部客户进行通信的。为此,如果没有端口映射的话,用户如果要同时访问内部的WEB服务器与ERP服务器,则就需要有两个公网IP地址。但是,大家都知道现在公网IP地址严重缺乏。在没有足够多的IP地址的情况下,该如何实现这种需求呢?那就知道通过端口映射来完成。

如上图所示,用户需要访问企业内部的WEB服务与ERP服务器,他只需要知道NAT服务地址与WEB服务器与ERP服务器所采用的端口即可。如果

WEB服务器采用的端口为80,

ERP服务器所采用的端口为5050。

而NAT服务器的IP地址假设为202.96.92.100的话,

 

那么当用户访问WEB服务器时,只需要输入http:// 202.96.92.100即可。由于HTTP协议默认采用的是80端口,故这里不用配置端口号。如果WEB服务器中把这个端口改为了3000,则在访问的时候就需要使用http:// 202.96.92.100:3000(地址+端口号)的形式了。用户要访问内部的ERP服务器也是类似的,只要把NAT服务器的地址以及ERP服务器所采用的端口在客户端上进行配置即可。

可见通过NAT服务器的端口映射功能,可以让外部用户同时访问企业内部的WEB服务器与ERP服务器。

那要实现这个需求具体该如何配置呢?

NAT服务器让内部的局域网用户可以连接到互联网,以便用户能够收发互联网邮件、浏览互联网上的网站等等。但是默认情况下外部用户是不能够访问内部的服务器。如果需要实现以上功能的话,就需要进行专门的配置。

如上图中,

内部局域网计算机(192.168.0.2)为WEB服务器,其采用的端口为80。

如果现在外部用户需要访问这个WEB服务器站点,则用户只知道这个WEB服务器的地址为202.96.92.100(NAT服务器的地址)。

而WEB服务器默认采用的端口为80。当外部用户通过浏览器访问企业内部的WEB服务器时,

他会在浏览器中输入http:// 202.96.92.100路经来连接网站。

NAT服务器会将此请求发送给内部的计算机WEB服务器(192.168.0.2),并由WEB服务器将这个请求转发给端口为80的软件来负责。WEB服务器会将网页传送给NAT服务器,再由NAT服务器负责将网页传送给外部用户的计算机。

如果用户要访问内部的ERP服务器,其过程也是如此。

那么现在的问题是,NAT服务器怎么判断要把用户HTTP请求发送给服务器(192.168.0.2)而不是发送给(192.168.0.3)呢?

这主要是根据端口来判断的。也就是说在NAT服务器中有一个端口映射的规则,只要用户访问的目的端口是80,就把这个请求转发给WEB服务器;若请求的端口是5050,则就把这个请求发送给ERP服务器。这就是端口映射的实质。了解这个内容之后,那么了解下面的配置也就简单多了。打开路由和远程访问主控制窗口,选择要配置的服务器。然后选择IP路由选择、NAT/基本防火墙。并双击右方对外连接的网络接口(注意这里不要选择连接内网的网络接口),选择服务和端口标签。然后直接从服务列表中选取要对外开发的服务,如选择WEB服务器。在公用地址中选择在此接口,表示由互联网服务提供商指派的NAT服务器的公网IP地址。然后再设置,如果把这个服务请求转发给内部的IP地址为192.168.0.2的WEB服务器。通过这个简单的配置,就实现基于端口的映射。

 

三、改善NAT服务器的性能与便利性。

可见这个端口映射配置是很简单的。但是其难点在于如何提高这个NAT服务器的性能,如何让用户使用的更加方便。这是网络管理员所需要考虑的。对此笔者有如下几个建议可供大家参考。

1、利用域名来代替IP地址。当用户访问企业内部的网站服务器时,如果让他们输入服务器的IP地址,对普通用户来说可能有点难度。要记住这202.96.92.100十一个没有丝毫关系的数字有很大的难度。如果能够把这个IP地址转换为有实际意义的网址那就最好了。在企业内部,可以自己部属一个DNS服务器,把IP地址转换为网址。那么内部员工可以直接通过网址来访问WEB服务器。但是在互联网上,企业可不能自己随便定义域名。为了提高用户访问的便捷性,企业网络管理员最好能够像当地的域名注册机构,申请一个合适的域名并关联到自己的NAT服务器公网IP地址。那么以后外部用户访问内部WEB服务器时,只需要输入像新浪那样的地址就可以了。而不用输入这些难以记忆的地址。

2、如果企业可以申请到多个IP地址的话,那么最好能够分开来部署。即企业可以申请两个ADSL帐号。其中一个专门用来连接内部的服务器;而另外一个用来内部员工跟互联网的通信。这么做主要是为了减轻NAT服务器的压力,提高其性能。如企业只有一个ADSL帐号的话,那么无论是外部用户访问企业内部服务器;还是企业内部员工访问互联网,其数据流都要通过这台NAT服务器来处理。为此,如果企业数据流量比较大或者NAT服务器配置不怎么理想的话,那么很可能这个NAT服务器就成为了企业网络访问的瓶颈资源。如果把他们分开,则可以减轻NAT服务器的压力,提高外部用户访问企业内部服务器的效率。

3、配置合适的ICMP数据包策略,以加强阻挡黑客利用ICMP的攻击行为。使用ICMP攻击的原理实际上就是通过Ping大量的数据包使得NAT服务器的CPU使用率居高不下而崩溃。一般情况下黑客通常在一个时段内连续向计算机发出大量请求而导致CPU占用率太高而死机。而且会使用多台肉鸡同时向NAT服务器发送数据包。基于ICMP的攻击可以分为两大类,一是ICMP攻击导致拒绝服务;另外一个是基于重定向的路由欺骗技术。无论是哪一类攻击,都会给NAT服务器产生致命的影响。为此为了NAT服务器的安全,最好配置合适的ICMP包策略。如可以拒绝响应别人的ICMP请求。如此攻击者就无法对NAT服务器发起ICMP攻击了。

 

SSH隧道与端口转发及内网穿透

大家都知道SSH是一种安全的传输协议,用在连接服务器上比较多。不过其实除了这个功能,它的隧道转发功能更是吸引人。下面是个人根据自己的需求以及在网上查找的资料配合自己的实际操作所得到的一些心得。

SSH/plink命令的基本资料:

首先,认识下这三个非常强大的命令:

ssh -C -f -N -g -L listen_port:DST_Host:DST_port user@Tunnel_Host
ssh -C -f -N -g -R listen_port:DST_Host:DST_port user@Tunnel_Host
ssh -C -f -N -g -D listen_port user@Tunnel_Host

相关参数的解释:
-f Fork into background after authentication.
后台认证用户/密码,通常和-N连用,不用登录到远程主机。

-L port:host:hostport
将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport

-R port:host:hostport
将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport

-D port
指定一个本地机器 “动态的’’ 应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.

-C Enable compression.
压缩数据传输。

-N Do not execute a shell or command.
不执行脚本或命令,通常与-f连用。

-g Allow remote hosts to connect to forwarded ports.
在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接。注:这个参数我在实践中似乎始终不起作用。

以上摘录自:http://chenweiguang.blogspot.com/2009/03/ssh.html

建立本地SSH隧道例子

在我们计划建立一个本地SSH隧道之前,我们必须清楚下面这些数据:

  1. 中间服务器d的IP地址
  2. 要访问服务器c的IP地址
  3. 要访问服务器c的端口

现在,我们把上面这张图变得具体一些,给这些机器加上IP地址。并且根据下面这张图列出我们的计划:

Chapter 8 Secure Network (ssh端口映射) - linux-ul - unix-EA

 

  1. 需要访问234.234.234.234的FTP服务,也就是端口21
  2. 中间服务器是123.123.123.123

现在我们使用下面这条命令来达成我们的目的(192.168.0.100上执行)

1.ssh -N -f   -L    2121:234.234.234.234:21    123.123.123.123

2.ftp://localhost:2121        # 现在访问本地2121端口,就能连接234.234.234.234的21端口了

这里我们用到了SSH客户端的三个参数,下面我们一一做出解释:

  • -N 告诉SSH客户端,这个连接不需要执行任何命令。仅仅做端口转发
  • -f 告诉SSH客户端在后台运行
  • -L 做本地映射端口,被冒号分割的三个部分含义分别是
    • 需要使用的本地端口号
    • 需要访问的目标机器IP地址(IP: 234.234.234.234)
    • 需要访问的目标机器端口(端口: 21)
  • 最后一个参数是我们用来建立隧道的中间机器的IP地址(IP: 123.123.123.123)

 

我们再重复一下-L参数的行为。-L X:Y:Z的含义是,将IP为Y的机器的Z端口通过中间服务器映射到本地机器的X端口。

在这条命令成功执行之后,我们已经具有绕过公司防火墙的能力,并且成功访问到了我们喜欢的一个FTP服务器了。

如何建立远程SSH隧道

通过建立本地SSH隧道,我们成功地绕过防火墙开始下载FTP上的资源了。那么当我们在家里的时候想要察看下载进度怎么办呢?大多数公司的网络是通过路由器接入互联网的,公司内部的机器不会直接与互联网连接,也就是不能通过互联网直接访问。通过线路D-B-A访问公司里的机器a便是不可能的。也许你已经注意到了,虽然D-B-A这个方向的连接不通,但是A-B-D这个方向的连接是没有问题的。那么,我们能否利用一条已经连接好的A-B-D方向的连接来完成D-B-A方向的访问呢?答案是肯定的,这就是远程SSH隧道的用途。

与本地SSH一样,我们在建立远程SSH隧道之前要清楚下面几个参数:

  • 需要访问内部机器的远程机器的IP地址(这里是123.123.123.123)
  • 需要让远程机器能访问的内部机器的IP地址(这里因为是想把本机映射出去,因此IP是127.0.0.1)
  • 需要让远程机器能访问的内部机器的端口号(端口:22)

在清楚了上面的参数后,我们使用下面的命令来建立一个远程SSH隧道

1.ssh -N -f -R 2222:127.0.0.1:22      123.123.123.123

现在,在IP是123.123.123.123的机器上我们用下面的命令就可以登陆公司的IP是192.168.0.100的机器了。

1.ssh -p 2222 localhost

-N,-f 这两个参数我们已经在本地SSH隧道中介绍过了。我们现在重点说说参数-R。该参数的三个部分的含义分别是:

  • 远程机器使用的端口(2222)
  • 需要映射的内部机器的IP地址(127.0.0.1)
  • 需要映射的内部机器的端口(22)

例如:-R X:Y:Z 就是把我们内部的Y机器的Z端口映射到远程机器的X端口上。

建立SSH隧道的几个技巧

自动重连

隧道可能因为某些原因断开,例如:机器重启,长时间没有数据通信而被路由器切断等等。因此我们可以用程序控制隧道的重新连接,例如一个简单的循环或者使用 djb’s daemontools . 不管用哪种方法,重连时都应避免因输入密码而卡死程序。关于如何安全的避免输入密码的方法,请参考我的 如何实现安全的免密码ssh登录 。这里请注意,如果通过其他程序控制隧道连接,应当避免将SSH客户端放到后台执行,也就是去掉-f参数。

保持长时间连接

有些路由器会把长时间没有通信的连接断开。SSH客户端的TCPKeepAlive选项可以避免这个问题的发生,默认情况下它是被开启的。如果它被关闭了,可以在ssh的命令上加上-o TCPKeepAlive=yes来开启。

另一种方法是,去掉-N参数,加入一个定期能产生输出的命令。例如: top或者vmstat。下面给出一个这种方法的例子:

1.ssh -R 2222:localhost:22 123.123.123.123 “vmstat 30”

检查隧道状态

有些时候隧道会因为一些原因通信不畅而卡死,例如:由于传输数据量太大,被路由器带入stalled状态。这种时候,往往SSH客户端并不退出,而是卡死在那里。一种应对方法是,使用SSH客户端的ServerAliveInterval和ServerAliveCountMax选项。 ServerAliveInterval会在隧道无通信后的一段设置好的时间后发送一个请求给服务器要求服务器响应。如果服务器在 ServerAliveCountMax次请求后都没能响应,那么SSH客户端就自动断开连接并退出,将控制权交给你的监控程序。这两个选项的设置方法分别是在ssh时加入-o ServerAliveInterval=n和-o ServerAliveCountMax=m。其中n, m可以自行定义。

如何将端口绑定到外部地址上

使用上面的方法,映射的端口只能绑定在127.0.0.1这个接口上。也就是说,只能被本机自己访问到。如何才能让其他机器访问这个端口呢?我们可以把这个映射的端口绑定在0.0.0.0的接口上,方法是加上参数-b 0.0.0.0。同时还需要打开SSH服务器端的一个选项-GatewayPorts。默认情况下它应当是被打开的。如果被关闭的话,可以在/etc /sshd_config中修改GatewayPorts no为GatewayPorts yes来打开它。

通过SSH隧道建立SOCKS服务器

如果我们需要借助一台中间服务器访问很多资源,一个个映射显然不是高明的办法(事实上,高明确实没有用这个方法)。幸好,SSH客户端为我们提供了通过SSH隧道建立SOCKS服务器的功能。

通过下面的命令我们可以建立一个通过123.123.123.123的SOCKS服务器。

1.ssh -N -f -D 1080 123.123.123 # 将端口绑定在127.0.0.1上

2.ssh -N -f -D 0.0.0.0:1080 123.123.123.123 # 将端口绑定在0.0.0.0上

通过SSH建立的SOCKS服务器使用的是SOCKS5协议,在为应用程序设置SOCKS代理的时候要特别注意。

以上摘录自:http://blog.jianingy.com/content/…

@@@@@@@@@@@@@@@@@@@@@@@@@@@

1 > 反向隧道技术

情景:节假日需要回公司加班。但是公司是内网,使用NAT,所以没办法连回去。

现在公司机器(LAN_ip)上执行

ssh -NfR 2222:localhost:22 home_ip

-R : 建立反向连接 将 home_ip port转发

现在,到home_ip上面
ssh localhost -p 2222
就跑在NAT后面的公司机器。就是后门了。灰鸽子木马用的也是反向链接。

Destination (LAN_ip) <- |NAT| <- Source (home_ip)

2>端口转发

情景:本机不允许访问www.xxx.com这个网站,但是远程主机(remote_ip)可以。

ssh -f -N -L 31609:www.xxx.com:80 user@remote_ip

现在我们就可以在本地打开 http://localhost:31609 访问www.xxx.com了。

3> SOCKS代理

情景: 本机不允许访问某些网站,但是远程主机(remote_ip)可以,并且公司没有组织你连接remote_ip。

ssh -NfD 8888 user@remote_ip

现在在浏览器socks 5 proxy设置为localhost:8888,所有之前无法访问的网站现在都可以访问了。

@@@@@@@@@@@@@@@@@@@

古人以“夜不闭户”、“路不拾遗”来形容大治之世。他们认为大治时,人们的道德水平已经很高了。而早期Internet的形成似乎也是符合这种思想的。Internet的初衷是相互信任和相互分享,它的这种“信任”建立在“大治”甚至“天下大同”的假想上。随着互联网的商业化和平民化,Internet的安全性就显得越来越脆弱了,不仅网络攻击、网络诈骗盛行,也有一些网络管理者肆意检测、更改、阻断用户通信的行为SSH的一些特性在很多场合可以解决这些问题。

ssh的基本用法在命令行也强大之ssh一文中做了最基本的介绍。ssh是安全的远程登录工具,在与远程主机进行交互时,ssh协议把原始数据进行了加密并压缩,从而保证了数据在网络传输过程的安全。利用这一原理,我们也可以用ssh把其它的明文传输的TCP数据流通过ssh的连接传输,这就是本文要讲到的ssh转发/隧道技术。下图表示一个ssh连接(图片来自http://www.ssh.com)

ssh连接

ssh的转发有四类:远程转发、本地转发、动态转发和X转发。把TCP流重定向到ssh连接叫做“转发”,这个ssh连接叫做“隧道”。

假设场景:受限网络内主机A,受限网络防火墙F,受限网络外主机B,受限网络外主机C、D、E。用户为主机A的管理者且拥有主机B的ssh账号,B、C、D、E可以正常连接。因为防火墙F的策略,A与C、D、E完全不能连接,A与B受限连接(当A与B的连接内有关键字“SB”则阻断连接,且只能由A与B连接,不能由B主动连接,可类比为NAT)。
下图为场景图(用Dia v0.96.1绘制)

场景

一、远程转发

将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机才能转发特权端口.--摘自ssh的中文Manual
命令格式为:

?[Copy to clipboard]View Code BASH
ssh -R ::

假设主机A提供了HTTP服务,即在受限网络内部可以访问的网页服务器。但这个服务因为防火墙策略或者NAT路由的原因导致在Internet无法访问。那么我们就可以将本地的HTTP服务远程转发到Internet上的主机B

?[Copy to clipboard]View Code BASH
ssh -fNgR 80:localhost:80 root@host-B

然后在Internet上可以通过访问 http://host-B来访问主机A上的HTTP服务了

如果没有主机B的root账号,则只能远程转发到1024以后的端口号

?[Copy to clipboard]View Code BASH
ssh -fNgR 8080:localhost:80 lige@host-B

然后在Internet上可以通过访问http://host-B:8080来访问主机A上的HTTP服务。
值得注意的是搭建了wordpress的主机只能运行在80端口,如果转发后的端口不是80,那么将无法使用,这应该算是wp的bug吧

而且因为主机A到主机B之间是通过隧道连接的,即使网页中含有关键字“SB”,也无法被大防火墙检测到(泪流满面,终于讲到关键了)

附加参数简要说明:

?[Copy to clipboard]View Code BASH
-N      不执行远程命令. 用于转发端口.  -n      把 stdin 重定向到 /dev/null (实际上防止从 stdin 读取数据).  ssh在后台运行时一定会用到这个选项. 它的常用技巧是远程运行 X11 程序.  -f      要求 ssh 在执行命令前退至后台. 它用于当 ssh 准备询问口令或密语,但是用户希望它在后台进行. 该选项隐含了 -n 选项. 在远端机器上启动X11 程序的推荐手法就是类似于 ssh -f host xterm 的命令.  -C      要求进行数据压缩  -g      允许远端主机连接本地转发的端口

关于建立隧道和使用隧道的网络原理,见文章末尾

二、本地转发

将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. --摘自ssh的中文Mannul

它的命令格式为

?[Copy to clipboard]View Code BASH
ssh -L ::

和远程转发原理类似但方向相反。假设主机B有HTTP服务,但因为受限网络内其它主机因憎恶“大防火墙”F而不愿意直接访问主机B(这种心理我也有)。那就可以通过本地转发了

?[Copy to clipboard]View Code BASH
ssh -fNgL 80:localhost:80 root@host-B

因为和远程转发类似,后面就不再详述。

三、动态转发

指定一个本地机器 “动态的” 应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接,该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS 协议, ssh 将充当 SOCKS 服务器.只有 root 才能转发特权端口. --摘自ssh的中文manual

可以这样理解,远程转发和本地转发都是在隧道上传输一个服务,比如例子中的HTTP数据流。而动态转发则是为了在隧道上传输多种不确定的网络服务。它的表现就把远端ssh服务器当作了一个安全的代理服务器。

命令格式为

?[Copy to clipboard]View Code BASH
$ ssh -D

假设主机A想要访问受限网络所限制访问的主机C、D、E等,或者想要访问主机B上的“SB”内容。则可有D选项建立动态隧道

?[Copy to clipboard]View Code BASH

ssh -CfNg -D 8888 lige@host-B

然后你就有了一个安全的socks 5代理。这个代理ip是127.0.0.1,端口为刚才指定的8888。如何使用socks 5代理在本文就不再讲了。大防火墙可能还存在一些技术来防止socks 5代理,可以参考socks代理的远端DNS解析一文

还有一个plink工具,包含在PuTTY软件包,可以在windows和linux下使用,它的格式为:

?[Copy to clipboard]View Code CMD

PLINK.EXE -C -D 127.0.0.1:7777 -N -pw SSH密码 SSH用户名@SSH的IP地址

四、X转发

X转发是一个令人惊奇但实际上用处不大的功能。因为我所能管理的远端主机都是无图形界面的,所以本部分内容我不保证正确。

大家都知道GUI软件与X之间也是通过TCP连接的,所以X转发与其它转发也没有本质区别,甚至它简单得都不应该和其它几种转发相提并论。X转发用的选项为”-X”

首先要在客户端指定X Server的位置

?[Copy to clipboard]View Code BASH

export DISPLAY=:.

然后执行

?[Copy to clipboard]View Code BASH

 ssh -X lige@hot-B

补充:可能的问题:

1. ssh的基本用法
http://blog.lilinux.net/2010/02/command-ssh/以及ssh的man文档

2. windows下的ssh客户端
PuTTY和其中的plink

3. 如何查看隧道是否建立完善
查看进程:

?[Copy to clipboard]View Code BASH

ps aux | grep ssh

查看端口:

?[Copy to clipboard]View Code BASH

netstat -ntl

4. 因为F,连接还是不稳定,隧道经常无法使用
去除-N,-n,-f选项,进入远程shell,输入一些需要频繁交互数据的命令,使连接一直处于活动状态。比如

?[Copy to clipboard]View Code BASH

top

我更推荐用这样的命令,对系统的负载消耗更小(而且更加美观)

?[Copy to clipboard]View Code BASH

watch -n1 "date"

5. 更多的实例
本文写的例子都是假设场景,近期将写一个实例应用。预计网址为http://blog.lilinux.net/2010/02/ssh-instance/

附ssh隧道原理

对网络原理不太懂或不感兴趣的可以忽略此部分

总的来说:Tunnel实际上是一个TCP连接,这个连接和普通的SSH登录的连接并没有本质上的区别

假设有两台主机A和B,IP分别是IP_A和IP_B,是要把主机A的22端口映射到主机B的10022端口

连接的建立过程是这样的:

1. 建立TUNNEL (在A主机上执行命令)
ssh命令,把A的端口映射到B主机(ssh -NfR 10022:localhost:22 USER_B@IP_B)
这个步骤实际上是这样的:
(1)ssh命令是ssh客户端,这条命令是指在A主机上登录B主机,并且A主机请求将A主机的22号端口映射到B主机的10022端口。
(2)B主机接受远程登录请求后,检测发现用户的权限足以创建10022端口,且10022端口并未使用。则B主机开启一个监听端口:10022
(3)这条命令成功结束后,A主机有了一个后台进程登录到B主机,这个登录的连接正是“TUNNEL”。
而B主机相应也有这么一个后台进程,此外B主机还增开了一个监听端口:10022
(4)在这个过程中,B是Server,A是Client。那么A是以一个任意端口连接到B的ssh监听端口。所设这个连接是
IP_A:12345 —— IP_B:22

2. 连接映射端口 (在B主机上执行命令)
连接映射端口 ( ssh USER_A@localhost -p 10022)
这个步骤实际上是这样的:
(1)主机B连接自己的一个监听端口10022
于是主机B以一个任意的端口连接10022: IP_B:23456 ——- IP_B:10022
(2)10022端口实际是由主机B的sshd来维护的,sshd发现有连接到10022的端口的数据。
将数据封装成ssh包,通过已经建立好的TUNNEL传输到对端主机A的12345端口(TUNNEL建立时的初始端口)
(3)主机A的12345端口收到数据后,经过TUNNEL的建立进程的处理(解开ssh包),把数据转到主机A的端口22(建立TUNNEL时指定的端口)
(4)因此,这个反向的连接就建立起来了

3. TUNNEL与TCP连接的关系
(1)TUNNEL本质是一个TCP连接
(2)TUNNEL的作用用于传输其它TCP连接的数据
(3)对用户而言,TUNNEL就是它们可见的TCP连接传输的一个“隧道”

Chapter 8 Secure Network (ssh端口映射) - linux-ul - unix-EA

 如需转载,请注明出处:http://blog.lilinux.net/2010/02/ssh-tunnel/

题目有点长
其实来自于一个朋友的问题
他的oracle跑在linux服务器上
远程的linux服务器并没有跑在图形界面下(runlevel=5)
而是跑在字符模式下(runlevel=3)
而他又想用图形界面来管理oracle
我翻了翻资料
找出一种方法
在一台图形界面的linux下(虚拟机也行,其实不是linux也行,关键是本地得有X server)起一个控制台
用命令行ssh加参数”-X”连上远程的linux服务器
像这样
ssh -X oracle@1.1.1.1
这里”1.1.1.1″是远程linux服务器的ip地址
这样连上去之后
直接就可以用以前只有在图形界面上才能用的命令
如oracle管理的图形程序”dbca”

这个原理很简单
因为远程的sshd支持x11 forward
那么他起x程序的时候
就会把x的包通过ssh转回来到ssh客户端的机器上来
而ssh客户端这边跑得有x server
所以就能正确接收x包并显示出来

其实在windows下也可以通过安装x server软件来实现一样的效果
比如x manager就可以
具体用法不在详述

这里的关键在于
远程的sshd需要支持x11 forward
不过不要担心
一般情况下
缺省是支持的

 

SSH端口转发(本地端口转发、远程端口转发、动态端口转发)工作原理、应用详解

Posted on March 1, 2011 by lesca

实验条件:
1.本文所述之实验,本地主机操作系统基于Ubuntu 10.04,远程主机操作系统基于BSD发行版
2.本地主机安装了ssh client(ssh),也安装了ssh server(sshd)
基础知识:
文章中客户端指ssh,用于发出连接请求;服务端指sshd,监听端口22。
安全通道是指ssh与sshd之间已建立的连接通道,该连接是加密的。

SSH 端口转发格式[1]

[-L [bind_address:]port:host:hostport]
[-R [bind_address:]port:host:hostport]
[-D [bind_address:]port]

动态端口转发
-D
这会使本地主机监听端口port,一旦与该端口建立连接,经过该端口的数据会被转发到安全通道发送到远程主机。远程主机的sshd会根据数据包的应用层协议(如HTTP)自动建立对应的连接。

$ ssh -D 7070 sisca@216.194.70.6

登陆前本地主机端口监听状态:

$ sudo netstat -lnput | grep ssh  tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      927/sshd  tcp6       0      0 :::22                   :::*                    LISTEN      927/sshd

登陆后本地主机端口监听状态:

$ sudo netstat -lnput | grep ssh  tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      927/sshd  tcp        0      0 127.0.0.1:7070          0.0.0.0:*               LISTEN      5205/ssh  tcp6       0      0 :::22                   :::*                    LISTEN      927/sshd  tcp6       0      0 ::1:7070                :::*                    LISTEN      5205/ssh

登陆后远程主机端口监听状态:

$ sockstat -4l  USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS  (什么都没有)

小结:我们发现,动态端口转发的时候确实是本地主机的ssh在监听端口7070的

本地端口转发
-L ::
这会使本地主机监听端口local_port,一旦与该端口建立连接,经过该端口的数据会被转发到安全通道,同时远程主机会与主机host的端口host_port建立连接。

$ ssh -L 7001:localhost:7070 sisca@216.194.70.6

登陆前本地主机端口监听状态:

$ sudo netstat -lnput | grep ssh  tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      927/sshd  tcp6       0      0 :::22                   :::*                    LISTEN      927/sshd

登陆后本地主机端口监听状态:

$ sudo netstat -lnput | grep ssh  tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      927/sshd  tcp        0      0 127.0.0.1:7001          0.0.0.0:*               LISTEN      3475/ssh  tcp6       0      0 :::22                   :::*                    LISTEN      927/sshd  tcp6       0      0 ::1:7001                :::*                    LISTEN      3475/ssh

登陆后远程主机端口监听状态:

$ sockstat -4l  USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS  (什么都没有)

小结:我们从中可以看出,本地端口转发的时候确实是本地主机的ssh在监听端口7001

远程端口转发
-R ::
这会使ssh_server(远程端)监听端口remote_port,一旦与该端口建立连接,经过该端口的数据会被转发到安全通道,并且本地主机会与主机host的端口host_port建立连接。

$ ssh -R 7001:localhost:7070 sisca@216.194.70.6

登陆前本地主机端口监听状态:

$ sudo netstat -lnput | grep ssh  tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      927/sshd  tcp6       0      0 :::22                   :::*                    LISTEN      927/sshd

登陆后本地主机端口监听状态:

$ sudo netstat -lnput | grep ssh  tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      927/sshd  tcp6       0      0 :::22                   :::*                    LISTEN      927/sshd

登陆后远程主机端口监听状态:

$ sockstat -4l  USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS  sisca    sshd       66196 7  tcp4   127.0.0.1:7001        *:*

小结:很明显,使用远程端口转发时,本地主机的端口监听并没有发生变化,相反远程主机却开始监听我们指定的7001端口

小提示:
这里的remote_port,local_port可以归并为listen_port,因此我们得到这样的助记格式:

ssh [-L|-R] ::

本地端口转发应用:[2]
背景:在实验室里有一台 LDAP 服务器(LDAP Server),但是限制了只有本机上部署的应用才能直接连接此 LDAP 服务器。现在我们想临时从本地机器(LDAP Client)直接连接到这个 LDAP 服务器,只需要在LDAP Client上运用本地端口转发:

$ ssh -L 7001:localhost:389 LdapServerHost

图1 本地端口转发

数据流向:
该命令首先使本地主机(LDAP Client)与远程主机(LDAP Server)建立一个SSH安全连接(安全通道)
然后本地主机会监听端口7001(注意是ssh在监听)
一旦本地LDAP客户端程序将数据发送到端口7001(即建立连接),远程主机上的sshd将主动与端口389(LDAP服务的端口)建立连接
从而来自LDAP客户端的请求转发到该端口389上(当然是通过安全通道)
注意:
本地主机有两个客户端:
1) ssh – 用于与远程主机建立ssh连接
2) LDAP客户端 – 用于与远程主机的LDAP服务程序进行通讯
远程主机对应地有两个服务进程:
1) sshd – 监听端口22
2) ldapd -监听端口389

远程端口转发应用:[2]
背景:这次假设由于网络或防火墙的原因我们不能用 SSH 直接从 LDAP Client 连接到 LDAP 服务器(LDAP Server),但是反向连接却是被允许的。那此时我们的选择自然就是远程端口转发了。我们这次在LDAP Server上运用远程端口转发,因此LDAP Client必须安装了sshd

$ ssh -R 7001:localhost:389 LdapClientHost

图2 远程端口转发

数据流向:
该命令首先使LDAP Server与 LDAP Client 建立一个SSH安全连接(安全通道)
然后LDAP Client开始监听端口7001(注意是sshd在监听)
一旦LDAP Client将数据发送到端口7001(即建立连接),LDAP Server上的ssh将主动与端口389(LDAP服务端口)建立连接
从而来自LDAP客户端的请求转发到该端口389上(当然是通过安全通道)

本地转发与远程转发的对比与分析
本地端口转发:ssh客户端发起ssh连接,并且监听指定端口
远程端口转发:ssh客户端发起ssh连接,但是由远程主机上的sshd监听指定端口

多主机转发应用[2]
图3 多主机端口转发

$ ssh -g -L 7001::389 

注意:我们在命令中指定了“ -g ”参数以保证机器(A)能够使用机器(C)建立的本地端口转发。

References:
[1] man 1 ssh
[2] IBM DeveloperWorks – 
实战 SSH 端口转发

 

Please support us if you feel this post is useful.

SSH 名为 secure shell, 是专门用来进行安全远程访问的协议。它无论从功能上、系统兼容性上、还是从安全上和Telnet和RSH相比都是足以取而代之。

 

在这个ARP欺骗横行,网上盗窃泛滥的年代,还有什么比安全更为重要的?

在这个遍地都是防火墙的年代,还有什么比通过一个端口就能访问所有业务更为重要的呢?

 

在矛和盾同样发达的年代,SSH可以给我们什么样的方便?

 

现代的UNIX类操作系统,无一例外地将SSH,作为默认系统软件包进行安装。

 

最基本的连接方式:SSH Hostname

 

SSH 提供了多种不同的接入认证方式:

Password

Hostkey

…..

…..

 

其中常用的有 password, 和host public key, 如果使用password,则会产生用户交互的密码输入,如果使用host key, 则可以直接登录或直接执行远程命令。

 

SSH Client 和Server的交互,能实现很多其他非常有用的功能:

 

最基本的功能有如下选项:

 

SSH 会话内容的压缩,可以使用gzip压缩级别进行指定,以提高在慢速线路上数据传输效率。

 

SSH 本地端口转发,可以将本地某个端口和远程SSH服务器上、或SSH远程服务器可达的地址端口建立一种映射关系,使对本地端口的访问请求会透明地转发到远程服务器上。从远程服务器上所看到的来访请求源地址将是SSH服务器的地址。

 

Secure Network (ssh端口映射)-----图详细可以使用 - zhuzhu - 五事九思  (大连Linux主机维护)

SSH 远程端口反向转发,与上列相反, 远程端口反向转发建立后,远程客户机访问远程SSH服务器的某端口,SSH服务器将把来访请求通过SSH安全通道转发到SSH客户端或SSH客户端可达的服务器地址端口上,从而使远程客户机,可以正常访问内部服务器所提供的服务。

SSH 远程端口反向转发,与上列相反, 远程端口反向转发建立后,远程客户机访问远程SSH服务器的某端口,SSH服务器将把来访请求通过SSH安全通道转发到SSH客户端或SSH客户端可达的服务器地址端口上,从而使远程客户机,可以正常访问内部服务器所提供的服务。

Secure Network (ssh端口映射)-----图详细可以使用 - zhuzhu - 五事九思  (大连Linux主机维护)

这样,SSH客户端D,就可以通过访问SSH服务器B的端口D,从而达到访问业务服务器C上端口D的目的。

 

高级功能/用法有:

 

SSH 端口转发的接续。

由于现代的UNIX系统都默认带有SSH服务和客户端,所以当网络变得比较复杂、层次很多的时候,使用多台机器的端口转发接续,可以将在层次很深的内网服务,在不改变当前网络结构和防火墙配置的情况下,层层转发出来从而可以使外网用户很方便地使用该内网服务,而无须对现有网络构架和甚至防火墙配置作任何变动。而对最外层的防火墙只需要开放一个22端口(默认ssh服务端口)就能使授权的客户端访问全网业务。

 

 

SSH 动态端口转发。

SSHv2,同时还支持内置的SockS4 Server,将ssh 客户端的指定端口,作为一个远程SOCKS4 Server的端口。对SockS4Server的访问请求将通过,SSH Protocol 传输到 SSH 服务器, SSH服务器将请求转发到用户应用的真正目的服务器。

 

SSH 的 PPP通道。

结合UNIX PPPD,还可以在SSH的 PTS 通道上建立PPP LINK从而非常灵活的实现 IP over SSH 的VPN。这种方法,可谓SSH的终极用法,因为它解决了所有由于地址翻译而带来的应用层协议不兼容的问题(多播问题是否能解决尚未测试)。

 

SSH产品实战。

 

SecureCRT

VanDyke Software 的经典力作,几乎囊括了所有SSH客户端的功能,在此,SSH的标准功能就不多说了。说一些windows上的特色功能使SCRT变得非常灵活。

1、它拥有端口转发安全过虑器,可以灵活地允许或禁止其他客户机访问被SecureCRT所转发的本机端口。

2、同时还拥有VBSCript/Jscript/Perl 脚本功能,可以通过这三类脚本语言和远程服务器进行自动交互式执行。

3、可以自动和服务器上的Zmodem进行交互,实现基于TTY/PTS的Zmodem 文件传输(这个功能可在任何类型的会话中进行,并不局限于SSH类型的会话)。

4、自动和SecureFX匹配实现SFTP的文件传输功能(无需输入用户名密码,因为是基于已建立的SSH Session的,所以登录速度是非常快的)由于SecureFx带有拖放功能,和类似文件夹的拷贝粘贴功能,所以会给文件传输带来很大方便性(FTP还是很不方便的)。

5、支持命令行方式,可在CMD中实现一步登录并将端口转发作为参数输入(和UNIX的SSH基本没区别了)。

 

 

功能太多了,就不一一列举了。详细请查看VanDyke Software的主页和SecureCRT的帮助文件。

 

UniTTY

A Pure Java Based SSH 客户端。居然实现了几乎所有的SSH功能。而且更牛的是,实现了端口转发的动态加载。而且默认实现了SFTP over SSH的文件传输。只是字体有待改进。看惯了SecureCRT的优雅美观的字体,再用UniTTY可能就有些不习惯了。它的多协议支持能力也很特别,居然将VNC的客户端协议也加进来了。

UNIX SSH 客户端

完全基于OpenSSH,最标准的客户端。能完成所有SSH协议支持的功能,同时结合UNIX的脚本,能完成其他操作系统无法完成的很多任务。或配合完成前面所提到的一些用法!

NetSarang XSHELL

韩国人写的多协议客户端,和他另外一个在国内很流行的产品(Xmanager)配合使用很好。默认支持TAB窗口的SFTP,使用也比较方便,也同时支持双向的端口转发。

 

MindTerm

纯java的ssh客户端,非常著名的开源软件mindterm。

mindterm,居然提供了源代码真是不错,以后可以将expect也扔了。

而且该有的都有了(sockserver, 端口转发,反向转发,scp,telnet,zlib compression,keepalive等),还额外提供了ftp 协议桥接sftp的功能,就是有一点不方便,在哑终端方式启动,需要X11Display支持。

 

zenith 2007.9.10

 

 

网的朋友苦于没有合法 ip,不能对外提供 internet 服务。解决方案很多,可以通过在网关做端口映射,或其他的辅助软件等。

本文介绍两种比较简单实用的方法,利用 ssh 这个强大的工具。
(以下方法不分平台,都适用)

案例一、
内网主机 A ,开了 http,ftp ,http ,vnc,sshd,socks5,cvs 等服务。无合法 ip 地址。

外网主机 B ,开了 sshd 服务。有合法 ip : 218.xxx.xxx.xxx

我们的目的是让 B 能访问 A 上的各种服务。

步骤:
1、A(内网服务器)  知道 B ip 后,先用 ssh client 连上 B,命令如下:
ssh -R 1234:localhost:21      -l root  218.xxx.xxx.xxx

解释:
关于 ssh 的参数,请看 ssh –help
-L listen-port:host:port Forward local port to remote address
-R listen-port:host:port Forward remote port to local address
-L local (本地) -R :remote (远程)

-R 1234:localhost:21 其实做了个“端口转发(forward)”。
意思是主机 A 把本地的 21端口(对应ftp服务)映射为 B 的1234 端口(任意未被占用),同时 A 监听 B 的1234 端口。
在 B 上用 netstat -al | grep 1234 ,你能看到这个监听连接。
任何发送到 B 1234 端口的请求将被传送到 A的 21 端口。

2、B 用 ftp 工具(任意,如gftp) 连本地的 1234 端口,输入 A 的 ftp 用户和密码。
ftp localhost 1234

千万不要觉的奇怪,为什么连的是本地的地址。
举个不恰当例子,相当于 A 在 B 的房间里装了个***(监听端口),那么 B 在房间里说的话就通过***传送到了 A。

3、推广:
如果 B 没占用 21 端口的话,那么可以写成:
A使用: ssh -R 21:localhost:21 -l root 218.xxx.xxx.xxx
B使用: ftp localhost

如果你想使用 A 上的 http 或其他服务,只需改变服务端口:
http服务 :
A使用:ssh -R 1234:localhost:80 -l root 218.xxx.xxx.xxx
B使用:w3m http://localhost:1234

sshd服务:
A使用:ssh -R 1234:localhost:22 -l root 218.xxx.xxx.xxx
B使用:ssh localhost -p 1234

vnc 服务:
A使用:ssh -R 1234:localhost:5901(其他) -l root 218.xxx.xxx.xxx
B使用:vncviewer localhost:1

socks5服务:
A使用:ssh -R 1234:localhost:1080 -l root 218.xxx.xxx.xxx
B 略

cvs 服务:
A使用:ssh -R 1234:localhost:2401 -l root 218.xxx.xxx.xxx
B使用:cvs -d :pserver:root@localhost:1234/home/cvsroot login

这里是否一定要用 root ,涉及到权限问题,具体还得靠大家来总结经验。

案例二、
部分朋友会问了,这样的话只是两台机器的互相通讯,如何让广域网的人都能访问呢?
聪明的你,这时候可能已经有了答案。

内网主机 A ,开了 http,ftp ,http ,vnc,sshd,socks5,cvs等服务。无合法 ip 地址。
外网主机 B ,开了 sshd 服务。有合法 ip : 218.xxx.xxx.xxx
我们的目的是让 internet 上的任何主机能访问 A 上的各种服务。

步骤:
1、首先,B 的sshd 服务端做点小小的设置:
vi /etc/ssh/sshd.config
加入 GatewayPorts yes
然后重启 sshd 服务: /etc /init.d/ssh restart 或 /etc/init.d/sshd restart
(解释:
不加,默认会把监听端口绑定在 localhost 或 lo(127.0.0.1),这样除了 B自身别人是没法访问监听端口的。
加入 GatewayPorts yes,把监听端口绑定到 0.0.0.0 ,这样外部的所有机器都能访问到这个监听端口。
主要是考虑安全性问题,默认情况,只允许本地访问。

这里才是真正的难点,实验了一个晚上,累人呀!给点鼓励吧 :)

2、A 知道 B ip 后,先用 ssh client 连上 B,命令如下:
ssh -R 21:localhost:21 -l root 218.xxx.xxx.xxx
(事先确定 B 的21 端口未被占用)

3、分布在 internet 的其它客户机使用 ftp 工具(任意),连 B 21端口。

ftp 218.xxx.xxx.xxx 21

你会发现自己连上了内网 A 的ftp 服务。

此法和案例一完全一样。

internet ———>> B 21 端口———–>>A 21端口
可以叫做端口转发,或隧道技术,也可以称之为跳板(B),或反* 。呵呵,我瞎说的。。。

可能遇到的问题:

Country:/etc# ssh localhost -p 1234
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
be:5f:d2:45:66:4d:0c:9e:2b:6b:45:65:a7:b2:85:28.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:11
RSA host key for localhost has changed and you have requested strict checking.
Host key verification failed.
Country:/etc# ssh localhost -p 1234
root@localhost’s password:
Last login: Mon May 5 02:39:53 2003 from localhost
localhost root #

如上问题,请删除 ~/.ssh/known_hosts,然后再试。

点评:
当然 ssh 还有很多的功能没有用,如先用 ssh 连接 上去后,可以用 scp命令来存取文件,等等。
scp -P xxx user@host:path/file

其它突破网关传送文件的方式也千变万化。

优点是:
可以突破网关,一般情况下,向网管要求在网关上给你做端口映射是不现实的,但用此法你可以让要好的朋友给你做。
使用方案一:比较点对点传送文件比较方便,或使用ssh进行远程控制内网。
ssh本身是加密,保证安全可靠。

缺点也不少:
使用 ssh 加密,势必影响性能,可以用 -C 选项调节压缩率。
如果象方案二使用额外的服务器,数据都要服务器中转(我是这样认为,没跟踪过),势必影响速度。
公网的服务器不好找。

建议:恳请编程高手们根据类似得原理,做个端口转发小工具,效果会更好。

本文,雕虫小计,漏洞无数。旨在提供一种如何解决问题的思路,请大侠不要笑话。也请大家多多支持,共同提高。

特别感谢 :sleeve ,x11 兄,是他们帮助一起实现的。以及 irc.linuxfire.com 中的大伙:)

基于HTTP返回头信息的服务器时间同步

因为偶尔遇到由于各种原因,我们在使用ntpdate的时候无法成功的跟服务器同步时间的现象,而一般情况下我们对时间的精度要求都不是太高,所以想到可以使用根据HTTP头里面的信息来校时的做法。
之前看到一个使用php编写的脚本,但是考虑到很多机器是没有php环境的,因此选用shell来进行代码的编写,尽量保证通用。

PS:这篇文章正好测试一下Gist插件,看看效果如何。

使用Apache的mod_headers和mod_setenvif为静态文件取消Cookie

因为静态图片一般都不需要使用Cookie,因此,将静态文件的SetCookie头都去掉是一个很好的加快网站访问速度的办法。使用Apache的话,可以用mod_headers和mod_setenvif两个模块实现。

首先在httpd.conf中加载这两个模块,然后写上如下代码:
SetEnvIf mime image/.* unset-cookie
Header unset Set-Cookie env=unset-cookie

这样,当Apache再遇到类型为图片的文件时,就不会发送Set-Cookie头,自然可以减少一点流量的开销,加快网站的访问速度。

Ctrl与Caps Lock键的交换

Emacs和VIM之所以这样受程序员的喜爱,是因为两者都有高度的可定制性,以及丰富的快捷键组合。利用这些快捷键组合,让你能够手不离键盘,就能完成大多数的工作。其实,用鼠标操作神马的,效率是极其低下的……

话说Emacs中,用到最多的两个快捷键组合,就是Meta键和Ctrl键。对于我们普通的键盘,Meta键还好,离手很近。不过,对于Ctrl键,就离得比较远了…… 网上有网友推荐的做法,是用手掌去按Ctrl键,不过,这样的方法,对于普通键盘还不错,但是对于笔记本来说,也不太实用。

正规的Unix键盘的键位布局,Ctrl键应该是在现在标准键盘的Caps Lock位置的。这样,按起Ctrl键,就方便多了。

那要怎么交换这两个键的键位呢?重新买一个键盘? No!! 其实,也不用换键盘,我们完全可以用软件的方式来实现两个键位的交换。
下面是我从网上整理来的方法:

Win7下交换键位的设置

其实Win7下面,方法还比较多,一种是直接修改注册表,实现全局的替换,另外一种,是让两个键的交换,只在Emacs窗口激活的时候生效。至于哪个更好,完全根据你自己的需要。

局部替换大法

这种方法,需要用到一个辅助软件,那就是大名鼎鼎的Auto Hotkey,简称AHK

编辑一个脚本,输入如下内容,保存,reload,即可生效:
IfWinActive emacs; 判断当前激活的窗口是否是Emacs,这是根据窗口标题实现的,如果你的标题不一样,请替换一下

Control::Capslock; 把Control替换为Capslock

Capslock::Control; 把Capslock替换为Control

IfWinActive

全局替换大法

可以利用第三方工具,或者直接在注册表中修改键位映射关系

注册表位置:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] 如果没有此键,就新建一个

新建一个二进制值的Key,名叫:Scancode Map

输入如下的值:

00,00,00,00

00,00,00,00

03,00,00,00

3A,00,1D,00

1D,00,3A,00

00,00,00,00

前两行和最后一行,都是固定的,全部为0。第三行,表示你修改了几个键,其实我们只是改了两个键,不过最后那一行也要算进去,所以是3。

重点是在第四行和第五行。3A00,代表Caps Lock, 1D00,代表Ctrl。这一行,意思即为,将Caps Lock映射为Ctrl

第五行,就不用说了,意思刚好相反。

修改完毕后,重新登录Windows即可生效!

下面附上各个键位值的参考:

Escape 01 00

Tab 0F 00

Caps Lock 3A 00

Left Alt 38 00

Left Ctrl 1D 00

Left Shift 2A 00

Left Windows 5B E0

Right Alt 38 E0

Right Ctr l1D E0

Right Shift 36 00

Right Windows 5C E0

Backspace 0E 00

Delete 53 E0

Enter 1C 00

Space 39 00

Insert 52 E0

HOME 47 E0

End 4F E0

Num Lock 45 00

Page Down 51 E0

Page Up 49 E0

Scroll Lock 46 00

Mac OS下交换键位设置

Mac OS Lion下,非常简单,甚至不需要任何第三方软件,直接在键盘设置里面修改即可。当初我还google了一下文章,有的说需要装键盘驱动,有的说要用第三方软件,其实没那么麻烦,Lion已经有这个功能了……

限制SSH的登录IP

为了保证服务器的安全,我们可以对SSH的登录IP进行限制。要实现这个功能,有两个方法:
1.IPTABLES大法
使用如下指令可以将1.2.3.4添加到可访问的IP列表内。如果要添加多个IP,只要多次执行第一句即可。第二句只需要执行一次。
# All connectsion from address 1.2.3.4 to SSH (port 22)
iptables -A INPUT -p tcp -m state --state NEW --source 1.2.3.4 --dport 22 -j ACCEPT

# Deny all other SSH connections
iptables -A INPUT -p tcp --dport 22 -j DROP

执行完了之后别忘了service iptables save保存修改
2.使用hosts.allow和hosts.deny
按照如下方式修改/etc/hosts.allow
# /etc/hosts.allow
sshd: 1.2.3.0/255.255.255.0
sshd: 192.168.0.0/255.255.255.0

其中如果是单台电脑的话可以不加掩码直接写IP。掩码可以用/24之类的方法来表示。

然后,关键的一步到了。更改了/hosts.allow只是让这些IP可以访问,但是并没有禁止其余IP的访问!所以一定要记得修改/etc/hosts.deny
# /etc/hosts.deny
sshd: ALL

这样就可以禁止不在hosts.allow中的IP使用SSH连接服务器了。

顺便一说,修改/etc/ssh/sshd_config可以做到只允许某些用户访问或只禁止某些用户访问。这两项分别是:
AllowUsers bob chris
DenyUsers badness paula

最好再设置
PermitRootLogin no
禁用root登录保证安全。
注意,修改/etc/ssh/sshd_config需要重启SSD服务。使用servise ssh restart或service sshd restart来重启。

解决WordPress导致Apache的mod_status失效

今天申请了一个Linode账户,因为一直知道Linode的Longview很强大,于是准备体验一下。安装好之后发现自动检测到我运行了Apache,但是看不到具体的信息,因为我的Apache的Status页面没有配置好。
于是按照官方的教程进行配置,结果怎么访问都不成功。实验了多次并查找资料后发现,是我的Wordpress在捣鬼。
因为Wordpress启用了伪静态,所以所有的请求都会被重写向index.php,包括/server-status。于是直接导致了页面404。解决方法是在Wordpress的Rewrite规则中添加这一句:
RewriteRule ^(server-info|server-status) - [L]
这样如果Apache判断你的请求是server-info或server-status就会直接终止Rewrite,这样就不会将该请求重写到index.php,导致404了。

PS:在安装的时候还出现了一个小问题,就是发现在安装perl-DBD-MySQL的时候会失败,找不到依赖包。最后使用yum –enablerepo=remi install perl-DBD-MySQL的方式解决。

修复mod_spdy导致重定向循环

之前在别的服务器上做过一个测试网站,为了全部使用https就写了这么一个重定向规则在.htaccess中:
RewriteEngine On
RewriteCond %{HTTPS} off$ [NC]
RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]

之前工作的一直很好,直到我将apache的mod_spdy模块装上,准备给服务器部署上spdy支持。部署完spdy之后,该站的任何网页都打不开了,一直显示
This webpage has a redirect loop
但是使用IE浏览器的话还是正常的,可以正常的打开网页。于是查找资料,发现在启用了spdy协议之后,mod_rewrite就会获取不到正常的%{HTTPS}状态,从而导致无限的重定向,想让客户端使用https协议访问网站。在mod_spdy没有修复之前,有一个临时的解决办法,就是将重定向规则修改为如下这个样子:
RewriteEngine On
RewriteCond %{SERVER_PORT} ^80$ [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

其实这只是将判断是否是https访问的方法由判断协议变成了判断端口,如果检查到用户是用80端口访问的就进行重定向,否则就不管了。虽然这么写是可以的,但是因为端口写死了,如果有修改服务端口的需要的话,就需要单独再来调整这个规则,比较麻烦。所以还是看看官方能否找到支持mod_rewrite的办法吧~

Linux Mount时遇到already mounted or busy

今天在处理服务器故障的时候遇到了一个奇怪的问题,在使用mount尝试挂载磁盘的时候,始终提示:
Mount: /dev/xxx already mounted or /mnt busy
奇怪的是,使用
df -h

lsof -n
都找不到任何相关信息,看起来这块磁盘既没有挂载,也没有进程在写目录。但是就是挂载不成功。
后来搜索了一下发现了一个解决办法:
首先使用
dmsetup ls
查看能否看到Device Mapper信息。如果显示类似:
[root@]# dmsetup ls
ddf1_44656c6c202020201028001510281f033832b7a2f6678dab (253, 0)
ddf1_44656c6c202020201028001510281f033832b7a2f6678dab1 (253, 1)
那么执行两次
dmsetup remove xxxxxx
命令,将这两个Mapper信息删除,检查一下:
[root@]# dmsetup ls
No devices found
此时,再挂载磁盘就不会出现问题了。