HTTP/HTTPS自动加密上网方案

这里主要介绍电脑无需任何设置,就能够自动加密代理特定网站的HTTP/HTTPS协议。

 

方案介绍

 

涉及到的软件

  • BIND: 一个流行的域名解析服务器,我们可以设置哪些域名需要走加密线路。
  • Stunnel: 使用TLS对tcp协议进行加密,也就是对tcp建立一条加密线路。
  • SNI Proxy: 代理软件。对于HTTP协议,它可以根据Host请求头解析得出目标站IP;对于HTTPS协议,它可以根据SNI扩展中的域名解析得出目标站IP。

 

此方案优缺点

优点:
无需手动设置任何代理,就能够自动加密代理特定网站的HTTP或HTTPS协议
相对于我们常用的ssh隧道,ssh隧道是单路,而此方案是支持多并发连接,可以极大加速网站访问。

缺点:
对于代理HTTPS协议,需要发起HTTPS连接的客户端,比如浏览器支持TLS的SNI扩展。好消息是目前浏览器几乎都支持此扩展,但对于一些非浏览器的客户端,不支持SNI扩展。我们只能设置正向代理来解决此问题。

 

方案原理

流程图:
服务器安全

原理介绍:

  • 1、首先我们需要准备三台服务器,一台是内网DNS服务器(安装bind),一台是内网代理服务器(安装stunnel),另一台国外服务器(安装stunnel,sniproxy)。
  • 2、我们还需要设置DNS为内网的DNS,并在内网bind dns设置谷歌域名解析的IP为内网代理服务器
  • 3、当我们访问谷歌网站时,首先会向内网DNS服务器发送DNS A记录查询,此时内网DNS服务器会返回内网代理服务器的IP。
  • 4、浏览器得到谷歌域名的解析IP后(即内网代理服务器的IP),会向内网代理服务器发送HTTP或HTTPS请求。
  • 5、此时内网代理服务器(即stunnel),会接收到请求,经过加密,把请求转发到国外服务器(stunnel)的指定端口上。
  • 6、国外服务器(stunnel)接收到来自国内服务器(stunnel)的加密数据后,经过解密,把请求转发到sniproxy。
  • 7、sniproxy再根据HTTP Host请求头或者HTTPS sni扩展的域名解析出谷歌服务器的IP,并把请求转发给谷歌服务器。
  • 8、谷歌服务器收到来自sniproxy发送的请求后,马上返回网页内容给sniproxy,sniproxy再原路返回数据给浏览器。

 

方案实施

由于时间有限,我们仅在Ubuntu server 12.04演示安装。

环境介绍

  • 系统:Ubuntu server 12.04
  • 内网DNS IP: 10.96.153.201(主),10.96.153.204(从)
  • 内网代理服务器: 10.96.153.204
  • 国外服务器IP: 1.2.3.4

安装BIND9

1、在主DNS和从DNS安装bind,即10.96.153.201(主),10.96.153.204(从)。

  1. wget http://www.isc.org/downloads/file/bind-9-10-0b1-2/?version=tar.gz -O bind-9-10-0b1-2.tar.gz
  2. tar xzf bind-9-10-0b1-2.tar.gz
  3. cd bind-9-10-0b1-2
  4. ./configure –prefix=/usr/local/bind
  5. make && make install

2、配置主DNS服务器(10.96.153.201)
2.1、生成/usr/local/bind/etc/rndc.key密钥文件

  1. /usr/local/bind/sbin/rndc-confgen -a -k rndckey -c /usr/local/bind/etc/rndc.key

2.2、编辑/usr/local/bind/etc/named.conf,写入如何内容:

  1. include "/usr/local/bind/etc/rndc.key";
  2. controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndckey"; }; };
  3. logging {
  4. channel default_syslog { syslog local2; severity notice; };
  5. channel audit_log { file "/var/log/bind.log"; severity notice; print-time yes; };
  6. category default { default_syslog; };
  7. category general { default_syslog; };
  8. category security { audit_log; default_syslog; };
  9. category config { default_syslog; };
  10. category resolver { audit_log; };
  11. category xfer-in { audit_log; };
  12. category xfer-out { audit_log; };
  13. category notify { audit_log; };
  14. category client { audit_log; };
  15. category network { audit_log; };
  16. category update { audit_log; };
  17. category queries { audit_log; };
  18. category lame-servers { audit_log; };
  19. };
  20. options {
  21.     directory "/usr/local/bind/etc";
  22. pid-file "/usr/local/bind/var/run/bind.pid";
  23. transfer-format many-answers;
  24. interface-interval 0;
  25. forward only;
  26. forwarders { 202.96.128.166;202.96.134.133; };
  27. allow-query {any;};
  28. };
  29. zone "google.com" {
  30. type master;
  31. file "google.com.zone";
  32. allow-transfer { 10.96.153.204; };
  33. };

在这个named.conf文件中,我们只需要关心如下内容:
对于options{}区域,202.96.128.166和202.96.134.133这两个是ISP提供的本地DNS,需要修改为自己所在ISP的本地DNS。
对于zone “google.com”{}区域,这里定义了google.com域名的区域文件google.com.zone,还有允许10.96.153.204(即从DNS)同步区域文件。
2.3、建立google.com.zone区域文件

  1. $TTL 3600
  2. @ IN SOA ns1.google.com. hostmaster.google.com. (
  3. 2014072015  ; Serial
  4. 3600 ; Refresh
  5. 900 ; Retry
  6. 3600000 ; Expire
  7. 3600 ) ; Minimum
  8. @ IN NS ns1.google.com.
  9. @ IN NS ns2.google.com.
  10. ns1 IN A 10.96.153.201
  11. ns2 IN A 10.96.153.204
  12. @ IN A 10.96.153.204
  13. * IN A 10.96.153.204

对于这个区域文件,
ns1 IN A 10.96.153.201 指向第一个dns服务器,即主DNS。
ns2 IN A 10.96.153.204 指向第二个dns服务器,即从DNS。
@ IN A 10.96.153.204和* IN A 10.96.153.204指向内网的代理服务器(stunnel)。我们只需要修改这三个地方就好了。

3、配置从DNS服务器(10.96.153.204)
编辑named.conf,写入如下内容

  1. logging {
  2. channel default_syslog { syslog local2; severity notice; };
  3. channel audit_log { file "/var/log/bind.log"; severity notice; print-time yes; };
  4. category default { default_syslog; };
  5. category general { default_syslog; };
  6. category security { audit_log; default_syslog; };
  7. category config { default_syslog; };
  8. category resolver { audit_log; };
  9. category xfer-in { audit_log; };
  10. category xfer-out { audit_log; };
  11. category notify { audit_log; };
  12. category client { audit_log; };
  13. category network { audit_log; };
  14. category update { audit_log; };
  15. category queries { audit_log; };
  16. category lame-servers { audit_log; };
  17. };
  18. options {
  19.     directory "/usr/local/bind/etc";
  20. pid-file "/usr/local/bind/var/run/bind.pid";
  21. transfer-format many-answers;
  22. interface-interval 0;
  23. forward only;
  24. forwarders { 202.96.128.166;202.96.134.133; };
  25. allow-query {any;};
  26. };
  27.  
  28. zone "google.com" {
  29. type slave;
  30. file "google.com.zone";
  31. masters { 10.96.153.201; };
  32. };

配置从DNS就简单得多,只需要写入如上内容到named.conf文件。同样的,
options{}中202.96.128.166和202.96.134.133这两个是当地ISP本地dns。
zone “google.com”{}中10.96.153.201指明主DNS服务器IP。
4、启动bind dns服务器

  1. /usr/local/bind/sbin/named

安装Stunnel

1、在内网代理服务器和国外主机安装stunnel

  1. apt-get install stunnel4

2、内网代理服务器stunnel配置
编辑/etc/default/stunnel4,设置ENABLED=1。
编辑/etc/stunnel/stunnel.conf,内容如下:

  1. client = yes
  2. pid = /etc/stunnel/stunnel.pid
  3. [http]
  4. accept = 80
  5. connect = 1.2.3.4:8082
  6.  
  7. [https]
  8. accept = 443
  9. connect = 1.2.3.4:4433

此配置文件表示,监听了80端口,并把此端口流量转发到1.2.3.4:8082,监听了443端口,并把此端口流量转发到1.2.3.4:4433
3、国外服务器stunnel配置
3.1、生成ssl证书stunnel.pem文件

  1. openssl genrsa -out key.pem 2048
  2. openssl req -new -x509 -key key.pem -out cert.pem -days 1095
  3. cat key.pem cert.pem >> /etc/stunnel/stunnel.pem

3.2、编辑/etc/stunnel/stunnel.conf文件

  1. client = no
  2. [http]
  3. accept = 1.2.3.4:8082
  4. connect = 127.0.0.1:8082
  5. cert = /etc/stunnel/stunnel.pem
  6.  
  7. [https]
  8. accept = 1.2.3.4:4433
  9. connect = 127.0.0.1:4433
  10. cert = /etc/stunnel/stunnel.pem

此配置文件表示,监听了1.2.3.4:8082,并转发此地址流量到127.0.0.1:8082,监听了1.2.3.4:4433,并转发给地址流量到127.0.0.1:4433。
3.3、编辑/etc/default/stunnel4,设置ENABLED=1。
4、启动stunnel

  1. service stunnel4 start

安装sniproxy

sniproxy项目地址:https://github.com/dlundquist/sniproxy
1、安装sniproxy
同样只演示在ubuntu server 12.04安装。
1.1、安装UDNS

  1. mkdir udns_packaging
  2. cd udns_packaging
  3. wget http://archive.ubuntu.com/ubuntu/pool/universe/u/udns/udns_0.4-1.dsc
  4. wget http://archive.ubuntu.com/ubuntu/pool/universe/u/udns/udns_0.4.orig.tar.gz
  5. wget http://archive.ubuntu.com/ubuntu/pool/universe/u/udns/udns_0.4-1.debian.tar.gz
  6. tar xfz udns_0.4.orig.tar.gz
  7. cd udns-0.4/
  8. tar xfz ../udns_0.4-1.debian.tar.gz
  9. dpkg-buildpackage
  10. cd ..
  11. dpkg -i *.deb

1.2、安装sniproxy

  1. apt-get install autotools-dev cdbs debhelper dh-autoreconf dpkg-dev gettext libev-dev libpcre3-dev libudns-dev pkg-config
  2. wget https://github.com/dlundquist/sniproxy/archive/master.zip
  3. unzip master.zip
  4. cd sniproxy-master/
  5. dpkg-buildpackage
  6. cd ..
  7. dpkg -i *.deb

2、配置sniproxy
/etc/sniproxy.conf内容如下:

  1. user daemon
  2. pidfile /var/run/sniproxy.pid
  3. error_log {
  4.     syslog deamon
  5.     priority notice
  6. }
  7. listen 127.0.0.1:8082 {
  8.     proto http
  9.     table http_hosts
  10. }
  11. table http_hosts {
  12.         .*      *:80
  13. }
  14.  
  15. listen 127.0.0.1:4433 {
  16.     proto tls
  17.     table https_hosts
  18. }
  19. table https_hosts {
  20. .* *:443
  21. }

此配置文件表示,监听了127.0.0.1:8082地址,并解析http协议中的Host请求头为IP,然后转发请求到此IP;监听了127.0.0.1:4433地址,并解析TLS中SNI扩展中的域名为IP,并转发请求到此IP。
3、启动sniproxy

  1. sniproxy

 

结束

到目前为止,我们已经搭建完成了整套HTTP/HTTPS加密代理方案。方案中的HTTP明文协议,利用stunnel使用了TLS加密,变成了HTTPS协议,使得数据包无法被解析出明文。方案中的HTTPS协议,本身是加密的,但为了防止SNI扩展的中域名被嗅探,还是走了stunnel的加密通道。对于发送HTTPS请求而不支持SNI扩展的客户端,需要手动设置下代理。下一篇博文我们来介绍加密的正向代理方案。

CDNFly(原HttpGuard)介绍

CDNFly是基于openresty,以lua脚本语言开发的防cc攻击软件。而openresty是集成了高性能web服务器Nginx,以及一系列的Nginx模块,这其中最重要的,也是我们主要用到的nginx lua模块。CDNFly基于nginx lua开发,继承了nginx高并发,高性能的特点,可以以非常小的性能损耗来防范大规模的cc攻击。

功能介绍

多节点管理

CDNFly支持多节点管理,可以在主控端同步更新同一个节点组的防cc配置,nginx配置等

网站管理

支持在控制面板添加,编辑,删除网站

防CC功能

内置多种防CC方法,以应付不同的攻击强度,如根据请求频率,浏览器自动识别,人工滑动验证,人工验证码等。
除了内置的这几种规则,还可以自定义自己的规则防护。

自动开启防护

在未受攻击的时候我们不想开启防攻击模式以免影响用户体验,这时候可以使用自动开启防护的功能。可以设置好开启防护的条件来自动开启防护。

允许爬虫

在开启防护的时候,像百度,谷歌,搜狗等为我们带来流量的搜索引擎的爬虫可能就无法正常访问我们的网站,这时候我们开启允许爬虫的功能,就可以免受防攻击模式的影响。

监控中心

添加新节点后,自动配置对域名请求频率、域名带宽的监控,以及节点Nginx性能、负载、硬盘、网络等监控。方便我们来查看节点及域名的运行情况,或者根据监控数据来查找问题。

界面截图

节点管理

服务器安全

网站管理

服务器安全

防护规则

服务器安全

域名监控

服务器安全

节点监控

服务器安全

安装和演示

安装:http://devops.webres.wang/2017/06/httpguard-installation/
演示:超级管理员:http://httpguard-demo.webres.wang:88/admin/login.html(admin/guard)
普通用户:http://httpguard-demo.webres.wang:88/user/login.html(user/user)

更多CDNFly文档

http://devops.webres.wang/tag/httpguard/

联系作者

QQ: 452336092

当安全协议不安全了:OpenSSL漏洞

此漏洞危害特别严重,请重视。

 

今天是一个特别的日子,早上大家还在讨论XP停止服务的事,到处是相关的新闻和文章,到了下午,到处都是OpenSSL的漏洞消息了。

OpenSSL与SSL安全协议

什么是SSL安全协议,我记得在10年我写过一篇简单介绍的文章,小谈SSL安全协议(小谈SSL安全协议(原创)_Fooying_百度空间),大家不凡可以看看,以前的文章,大家就不要笑话了。

SSL,全称Secure Socket Layer,为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃听。简单的说,就是加密传输的数据,避免被截取监听等。

SSL应该是大家平时接触最多的安全协议了,大家可以看访问一些网址的时候,一般是http://开头,如果发现https://开头就是采用了SSL安全协议。比如,大家在登陆微信网页版的时候就可以看到:

服务器安全

一般来说,比如nginx,可以通过以下方式就可以进行配置:

# HTTPS server 
# 
server { 
listen 443; 
server_name localhost; 
 
ssl on; 
ssl_certificate /opt/nginx/sslkey/server.crt; 
ssl_certificate_key /opt/nginx/sslkey/server.key; 
 
location / {     
		root /home/workspace/;     
		index index.asp index.aspx;        
	} 
} 

 

大家可以看到,监听的是443端口,然后通过ssl on;来开启,同时通过ssl_certificate和sl_certificate_key配置证书和key文件,具体的就不多解释了,大家可以自己搜索下。

那么证书和key又是怎么一回事呢?接下来就要讲到OpenSSL了。

进行过nginx编译的同学都知道,在编译nginx的时候,如果想让nginx支持开启SSL,那么必须加一个–with-http_ssl_module 的配置项。那么又何让服务器支持这个配置项呢?又如何生成nginx配置中SSL所需要的证书和key文件呢?都是源于OpenSSL(openssl_百度百科)。

OpenSSL是一个强大的安全套接字层密码库,Apache使用它加密HTTPS,OpenSSH使用它加密SSH,但是,你不应该只将其作为一个库来使用,它还是一个多用途的、跨平台的密码工具。

大家平时如果采用公私钥的方式连接服务器,也是需要用到OpenSSL的。简单的理解,OpenSSL是一个强大的支持库,更是一个强大的密码工具。虽然要支持SSL协议不一定得采用OpenSSL,但是基本大部分的都是采用OpenSSL。

心脏出血的OpenSSL

相信前面简单的介绍能让大家了解到OpenSSL的重要性,也明白了SSL协议是做什么的,那么大家应该就可以理解,本来采用SSL协议是为了数据传输的安全性,是为了更安全,但是OpenSSL的漏洞直接导致了本该是让为了更安全的设置变成了致命的危险。

简单介绍下漏洞,这个漏洞是昨天国外的黑客曝光的,该漏洞可以获取HTTPS服务器的随机64K内存。这个漏洞被称为heartbleed,直译的话就是心脏出血。可能有部分同学没意识到这个64K有啥用错,读取内存又有啥用?

贴几张图:

这是笔者利用poc进行的一些测试(测试poc:http://s3.jspenguin.org/ssltest.py,直接python ssltest.py domain就可以了),大家可以看到,cookie甚至是明文帐号密码都直接爆出来了,有的还有代码源码(这个忘记截图了。。。)、SSL私钥(这个笔者没测试出来)等,那么影响有多大呢?看下wooyun的漏洞提交列表:

再给个来自zoomeye(ZoomEye – The Cyberspace Search Engine)的统计数据:

全国443端口:1601250,有33303个受本次OpenSSL漏洞影响

看了这些,称为”心脏出血”完全不为过。今天估计又有许多运维同学可忙的了。具体的漏洞分析我也不多说了,大家可以看wooyun上的文章(关于OpenSSL“心脏出血”漏洞的分析

安全防范

说了这么多,可能有些同学觉得都不要去访问那些是https的网站了,其实也大可不必,官方其实已经放出补丁了,修复方法:

升级到最新版本OpenSSL 1.0.1g
无法立即升级的用户可以以-DOPENSSL_NO_HEARTBEATS开关重新编译OpenSSL
1.0.2-beta版本的漏洞将在beta2版本修复

对于个人用户的话,大家不用太担心,虽然说影响有点大,不过问题主要是出在服务商,而且像那些大网站,比如微信、淘宝等都已经修复了,实在不放心,大家可以这几天暂时不要访问使用了SSL协议的网站进行登陆等操作,特别是网银等网站。另外,提供个在线检测的工具给大家:Test your server for Heartbleed (CVE-2014-0160)与我们团队弄的一个工具实验室 – SCANV,大家也可以访问前进行下检测。

结语

剩下的就不多说了,首先给那些连夜处理的运维和安全工作人员道声辛苦了。现在大家对安全越来越重视,这是好事,剩下的就是大家上网多小心些!

转自:http://zhuanlan.zhihu.com/fooying/19722474

使用jailkit chroot更改ssh用户根目录

安装jailkit

  1. cd /tmp
  2. wget http://olivier.sessink.nl/jailkit/jailkit-2.16.tar.gz
  3. tar xzf jailkit-2.16.tar.gz
  4. cd jailkit-2.16
  5. ./configure
  6. make
  7. make install
  8. cp extra/jailkit /etc/init.d/jailkit
  9. chmod u+x /etc/init.d/jailkit
  10. chkconfig jailkit on

初始化chroot环境

  1. jk_init -v -j /home/chroot sftp scp jk_lsh netutils extendedshell
  2. service jailkit start

新建devops.webres.wang用户

  1. useradd devops.webres.wang -m
  2. echo devops.webres.wang:password | chpasswd

chroot用户

  1. jk_jailuser -m -n -j /home/chroot –shell=/bin/bash devops.webres.wang

关于jailkit更详细的介绍请到:http://olivier.sessink.nl/jailkit/

OpenResty(nginx扩展)实现防cc攻击

防cc攻击,推荐使用HttpGuard

 

本文介绍使用openresty来实现防cc攻击的功能。openresty官网http://openresty.org/cn/index.html。下面是防cc攻击的流程图。
根据流程图,我们知道防cc攻击主要包括两部分,一是限制请求速度,二是给用户发送js跳转代码进行验证请求是否合法。
Nginx

一、安装依赖

centos:

  1. yum install readline-devel pcre-devel openssl-devel

ubuntu:

  1. apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl

二、luajit安装

  1. cd /tmp/
  2. git clone http://luajit.org/git/luajit-2.0.git
  3. cd luajit-2.0/
  4. make && make install
  5. ln -sf luajit-2.0.0-beta10 /usr/local/bin/luajit
  6. ln -sf /usr/local/lib/libluajit-5.1.so.2 /usr/lib/

三、openresty安装

  1. cd /tmp
  2. wget http://agentzh.org/misc/nginx/ngx_openresty-1.2.4.13.tar.gz
  3. tar xzf ngx_openresty-1.2.4.13.tar.gz
  4. cd ngx_openresty-1.2.4.13/
  5. ./configure –prefix=/usr/local/openresty –with-luajit
  6. make && make install

四、nginx配置

nginx.conf:

  1. http{
  2. [……]
  3. lua_shared_dict limit 10m;
  4. lua_shared_dict jsjump 10m;
  5.  
  6. <pre><code>server {
  7.     #lua_code_cache off;
  8.     listen       80;
  9.     server_name  devops.webres.wang;
  10.  
  11.     location / {
  12.         default_type  text/html;
  13.         content_by_lua_file "/usr/local/openresty/nginx/conf/lua";
  14.     }
  15.     location @cc {
  16.         internal;
  17.         root   html;
  18.         index  index.html index.htm;
  19.     }
  20. }
  21. </code></pre>
  22.  
  23. }

/usr/local/openresty/nginx/conf/lua文件:

  1. local ip = ngx.var.binary_remote_addr
  2. local limit = ngx.shared.limit
  3. local req,_=limit:get(ip)
  4. if req then
  5.         if req > 20 then
  6.                 ngx.exit(503)
  7.         else
  8.                 limit:incr(ip,1)
  9.         end
  10. else
  11.         limit:set(ip,1,10)
  12. end
  13.  
  14. local jsjump = ngx.shared.jsjump
  15. local uri = ngx.var.request_uri
  16. local jspara,flags=jsjump:get(ip)
  17. local args = ngx.req.get_uri_args()
  18. if jspara then
  19.     if flags then
  20.         ngx.exec("@cc")
  21.     else
  22.                 local p_jskey=”
  23.                 if args["jskey"] and type(args["jskey"])==’table’ then
  24.                          p_jskey=args["jskey"][table.getn(args["jskey"])]
  25.                 else
  26.                          p_jskey=args["jskey"]
  27.                 end
  28.         if p_jskey and p_jskey==tostring(jspara) then
  29.                         jsjump:set(ip,jspara,3600,1)
  30.                         ngx.exec("@cc")
  31.         else
  32.                         local url=”
  33.                         if ngx.var.args then
  34.                                 url=ngx.var.scheme.."://"..ngx.var.host..uri.."&amp;jskey="..jspara
  35.                         else
  36.                                 url=ngx.var.scheme.."://"..ngx.var.host..uri.."?jskey="..jspara
  37.                         end
  38.                         local jscode="<script>window.location.href=’"..url.."’;</script>"
  39.                         ngx.say(jscode)
  40.         end
  41.     end
  42. else
  43.     math.randomseed( os.time() );
  44.     local random=math.random(100000,999999)
  45.     jsjump:set(ip,random,60)
  46.     local url=”
  47.     if ngx.var.args then
  48.         url=ngx.var.scheme.."://"..ngx.var.host..uri.."&amp;jskey="..random
  49.     else
  50.         url=ngx.var.scheme.."://"..ngx.var.host..uri.."?jskey="..random
  51.     end
  52.     local jscode="<script>window.location.href=’"..url.."’;</script>"
  53.     ngx.say(jscode)
  54. end

lua代码部分解释:
1、1-12行是限速功能实现,第5和第10行表示10秒钟内容最多只能请求20次。
2、14-48行是验证部分,24行中的3600表示验证通过后,白名单时间为3600秒,即1小时。

update: 2013.5.26
1、修复JS无限跳转bug
2、增加随机种子

防止端口扫描shell脚本

网上有现在的防端口工具,如psad、portsentry,但觉得配置有点麻烦,且服务器不想再装一个额外的软件。所以自己就写了个shell脚本实现这个功能。基本思路是:使用iptables的recent模块记录下在60秒钟内扫描超过10个端口的IP,并结合inotify-tools工具实时监控iptables的日志,一旦iptables日志文件有写入新的ip记录,则使用iptables封锁源ip,起到了防止端口扫描的功能。 继续阅读防止端口扫描shell脚本

远程密令临时开启ssh端口

linux服务器,我们一般是通过ssh通道远程管理,这就需要我们开启ssh端口,如22。但开启端口有被暴力破解的风险,你会说可以设置复杂的密码或使用证书避免。就算破解不了密码,但openssh也可能会有漏洞,你会说可以更改ssh端口,但还是有可能被扫描出来。还有一种选择,我们可以只允许指定IP访问ssh,通过vpn登录管理服务器,但局限很明显,万一紧急情况vpn登录不上去了怎么办。下面给出一种个人觉得比较满意的解决方案,即使用iptables的recent模块,通过密令临时开启ssh端口。当然,密令需要保管好,防止外泄。
1、iptables规则设定

  1. #指定78字节的icmp数据包(包含IP头部20字节,ICMP头部8字节)通过被加入sshopen列表。
  2. iptables -A INPUT -p icmp –icmp-type 8 -m length –length 78 -m recent –set –name sshopen –rsource -j ACCEPT
  3. #检查sshopen列表是否存在你的来源IP,如果存在,即从第一次使用密令开始15秒钟内开启ssh端口22,超过15秒端口自动关闭,不再允许新连接,已连接的不会断开。
  4. iptables -A INPUT -p tcp –dport 22 –syn -m recent –rcheck –seconds 15 –name sshopen –rsource -j ACCEPT

2、临时开启ssh端口密令

  1. linux下:ping -s 50 host
  2. windows下:ping -l 50 host

3、我目前使用的iptables规则

  1. -A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
  2. -A INPUT -p tcp -m tcp –dport 80 -j ACCEPT
  3. -A INPUT -p tcp -m tcp –dport 443 -j ACCEPT
  4. -A INPUT -p tcp -m tcp –dport 123 -j ACCEPT
  5. -A INPUT -p icmp -m icmp –icmp-type 8 -m length –length 50 -m recent –set –name sshopen –rsource -j ACCEPT
  6. -A INPUT -p tcp -m tcp –dport 22 –syn -m recent –rcheck –seconds 15 –name sshopen –rsource -j ACCEPT
  7. -A INPUT -i lo -j ACCEPT
  8. -A INPUT -p icmp -m icmp –icmp-type 8 -j ACCEPT
  9. -A INPUT -p icmp -m icmp –icmp-type 11 -j ACCEPT
  10. -A OUTPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
  11. -A OUTPUT -o lo -j ACCEPT
  12. -A OUTPUT -p tcp -m tcp –dport 80 -j ACCEPT
  13. -A OUTPUT -p tcp -m tcp –dport 443  -j ACCEPT
  14. -A OUTPUT -p icmp -m icmp –icmp-type 8 -j ACCEPT
  15. -A OUTPUT -p icmp -m icmp –icmp-type 11 -j ACCEPT

参考:http://blog.onovps.com/archives/iptables-recent.html

iptables学习笔记

数据包流向顺序

我们来讨论数据包是以什么顺序、如何穿越不同的链和表的。稍后,在你自己写规则时,就会知 道这个顺序是多么的重要。一些组件是iptables与内核共用的,比如,数据包路由的判断。了解到这一点是 很重要的,尤其在你用iptables改变数据包的路由时。这会帮助你弄明白数据包是如何以及为什么被那样路 由,一个好的例子是DNAT和SNAT,不要忘了TOS的作用。 继续阅读iptables学习笔记

Linux简单处理CC攻击shell脚本

第一个脚本是通过查找日志中访问次数过多的ip,并用iptables屏蔽,600秒解封。

  1. #!/bin/bash
  2. btime=600
  3. attacks=20
  4. tmpBlockIPFile=/home/tmp_block_ip
  5. timestamp=$(date +%s)
  6. logPath="/home/ban.log"
  7.  
  8. #start detect bad ip
  9. badip=`tac /home/devops.webres.wang/access.log  | awk ‘
  10. BEGIN{
  11. cmd="date -d "1 minute ago" +%H%M%S"
  12. cmd|getline a
  13. }
  14. {
  15. $4 = substr($4,14,8)
  16. gsub(":","",$4)
  17. $4=$4+0
  18. a=a+0
  19. if ($4>=a){
  20. print $1,$7
  21. } else {
  22. exit;
  23. }
  24. }’ | egrep -v ‘.(gif|jpg|jpeg|png|css|js)’ | awk ‘{print $1}’ | sort | uniq -c | awk -v t="$attacks" ‘{$1=$1+0;t=t+0;if ($1>=t) print $2}’`
  25.  
  26. if [ ! -z "$badip" ];then
  27.     for ip in $badip;
  28.     do
  29.         if test -z "`/sbin/iptables -nL | grep $ip`";then
  30.             /sbin/iptables -I INPUT -s $ip -j DROP
  31.  
  32.             #record blocked ip
  33.             echo "$timestamp $ip" >> $tmpBlockIPFile
  34.             echo "$(date) $ip" >> $logPath
  35.         fi
  36.     done
  37. fi
  38.  
  39. #unblock ip
  40. if [ -f "$tmpBlockIPFile" ];then
  41.     ips=""
  42.     while read blockTime ip
  43.     do
  44.         ((interval=$timestamp – $blockTime))
  45.         if [ $interval -gt $btime ];then
  46.             ips="$ips $ipn"
  47.         fi   
  48.     done < $tmpBlockIPFile
  49.  
  50.     if [ "$ips" != "" ];then
  51.         for ip in `echo -e $ips`
  52.         do
  53.             sed -i "/$ip/d" $tmpBlockIPFile
  54.             /sbin/iptables -D INPUT -s $ip -j DROP
  55.         done
  56.     fi
  57. fi

将此代码保存为ban.sh,加入cronjob使每分钟执行一次。
此脚本的作用是:利用iptables屏蔽每分钟访问页面超过20的IP,这些页面已经排除图片,css,js等静态文件。
第二个脚本是通过在日志中查找cc攻击的特征进行屏蔽。

  1. #!/bin/bash
  2. keyword="cc-atack"
  3. badip=`tail -n 5000  /home/devops.webres.wang/log/access.log | grep "$keyword"  | awk ‘{print $1}’ | sort | uniq -c | sort -nr | awk ‘{print $2}’`
  4. if [ ! -z "$badip" ];then
  5. for ip in $badip;
  6. do
  7. if test -z "`/sbin/iptables -nL | grep $ip`";then
  8. /sbin/iptables -I INPUT -s $ip -j DROP
  9. fi
  10. done
  11. fi

keyword则是日志中cc的特征,替换成有效的即可。