【问题标题】:How to test if number of max connections (and max connection per second) is working如何测试最大连接数(以及每秒最大连接数)是否正常工作
【发布时间】:2017-03-04 20:40:14
【问题描述】:

我确实在我的 iptables 规则中添加了以下规则:

#limit numbeer of connections
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit  --connlimit-above 15 --connlimit-mask 32 -j DROP
iptables -t filter -I INPUT -p tcp --syn --dport 443 -m connlimit  --connlimit-above 15 --connlimit-mask 32 -j DROP
iptables -t filter -I INPUT -p tcp --syn --dport 8008 -m connlimit  --connlimit-above 15 --connlimit-mask 32 -j DROP

iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent
--set iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 2 --hitcount 25 -j DROP iptables -I INPUT -p tcp --dport 443 -m state --state NEW -m recent --set iptables -I INPUT
-p tcp --dport 443 -m state --state NEW -m recent --update --seconds 2 --hitcount 25 -j DROP iptables -I INPUT -p tcp --dport 8008 -m state --state NEW -m recent --set iptables -I INPUT -p tcp --dport 8008 -m state --state NEW -m recent --update --seconds 2 --hitcount 25 -j DROP

这是完整的 iptables 规则的样子:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  anywhere             anywhere             tcp dpt:ssh state NEW recent: UPDATE seconds: 60 hit_count: 3 TTL-Match name: sshprobe side: source mask: 255.255.255.255
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh state NEW recent: SET name: sshprobe side: source mask: 255.255.255.255
DROP       tcp  --  anywhere             anywhere             tcp dpt:8008 state NEW recent: UPDATE seconds: 2 hit_count: 25 name: DEFAULT side: source mask: 255.255.255.255
           tcp  --  anywhere             anywhere             tcp dpt:8008 state NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
DROP       tcp  --  anywhere             anywhere             tcp dpt:https state NEW recent: UPDATE seconds: 2 hit_count: 25 name: DEFAULT side: source mask: 255.255.255.255
           tcp  --  anywhere             anywhere             tcp dpt:https state NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
DROP       tcp  --  anywhere             anywhere             tcp dpt:http state NEW recent: UPDATE seconds: 2 hit_count: 25 name: DEFAULT side: source mask: 255.255.255.255
           tcp  --  anywhere             anywhere             tcp dpt:http state NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
DROP       tcp  --  anywhere             anywhere             tcp dpt:8008 flags:FIN,SYN,RST,ACK/SYN #conn src/32 > 15
DROP       tcp  --  anywhere             anywhere             tcp dpt:https flags:FIN,SYN,RST,ACK/SYN #conn src/32 > 15
DROP       tcp  --  anywhere             anywhere             tcp dpt:http flags:FIN,SYN,RST,ACK/SYN #conn src/32 > 15
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http-alt
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:8181
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:8008
DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy DROP)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

我想测试一下这个新政策是否有效。

我如何测试它?我尝试使用 apache 基准检查来自本地主机的某些连接是否正在断开:

ab -n 10000 -c 9000 http://www.tralev.com/web/main

但是从输出中我看不到任何连接确实断开了:

Failed requests:        82
   (Connect: 0, Receive: 0, Length: 82, Exceptions: 0)

(这个长度错误可能是由于服务器上的一些动态内容)。

那么我该如何修复我的 iptables 设置或设置一个测试以显示当前设置实际上将 IP 地址的连接数限制为 15(并且每秒最大连接数限制为 15)?

【问题讨论】:

    标签: iptables apachebench


    【解决方案1】:

    由于超过 24 小时没有人回复此消息,我编写了 Java 代码来测试服务器响应。下面的代码供参考。顺便说一句,我的 iptables 规则似乎不起作用(从执行代码)。

    public class TestConcurrentCalls {
    
      class Tester implements Runnable {
    
        String url;
        boolean error;
        TestConcurrentCalls parent;
    
        public Tester(String url, TestConcurrentCalls parent) {
          this.url = url;
          this.parent = parent;
        }
    
        @Override
        public void run() {
          String content = WebOperations.getFromURL(url).toString();
          if (content == null || content.length() < 10) {
            synchronized (parent) {
              parent.errors++;
            }
          } else {
            synchronized (parent) {
              parent.ok++;
            }
          }
        }
      }
    
      static public int errors = 0;
      static public int ok = 0;
    
      public void test(String url, int threads) {
        for (int thread = 0; thread < threads; thread++) {
          testOne(url);
        }
        int sleeps = 0;
        try {
          do {
            Thread.sleep(1000L);
            sleeps++;
          } while (threads > errors + ok || sleeps > 1000);
        } catch (InterruptedException ex) {
          Logger.getLogger(TestConcurrentCalls.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    
      public void testOne(String url) {
        Tester tester = new Tester(url, this);
        Thread thread = new Thread(tester);
        thread.start();
      }
    
      public static void main(String[] args) {
        TestConcurrentCalls test = new TestConcurrentCalls();
        test.test("http://www.tralev.com/web/main", 1000);
        System.out.println("Errors: " + errors + "    , ok: " + ok);
      }
    
    }
    

    这段代码使用的是我内部的WebOperations.getFromUrl方法,写法如下:

      public static StringBuilder getFromURL(String address) {
        return getFromURL(address, null);
      }
    
      public static StringBuilder getFromURL(String address,String referer) {
        return getFromURL(address, referer, 60, null); // wait one minute at most
      }
    
    
      public static StringBuilder getFromURL(String address,String referer, int maxSecondsToWait, String accept) {
    
        StringBuilder result=new StringBuilder();
        try {
            if(!address.toLowerCase().contains("://"))
                address="http://"+address;
            Logger.getLogger(WebOperations.class.getName()).info("URL for fetching " + address);
            URL url = new URL(address);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          connection.setConnectTimeout(maxSecondsToWait * 1000); 
          if (accept != null) {
            connection.setRequestProperty("Accept", accept);
          }
          connection.setReadTimeout(maxSecondsToWait * 1000);
          connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)");
          //connection.setRequestProperty("Accept","*/*");
          if (referer != null && !referer.equals("")) {
            connection.setRequestProperty("From", referer);
            connection.setRequestProperty("Referer", referer);
          }
    
          // Get all cookies from the server.
          // Note: The first call to getHeaderFieldKey() will implicit send
          // the HTTP request to the server.
          for (int i = 0;; i++) {
            String headerName = connection.getHeaderFieldKey(i);
            String headerValue = connection.getHeaderField(i);
    
            if (headerName == null && headerValue == null) {
              // No more headers
              break;
            }
            if ("Set-Cookie".equalsIgnoreCase(headerName)) {
              // Parse cookie
              String[] fields = headerValue.split(";\\s*");
    
              String cookieValue = fields[0];
              String expires = null;
              String path = null;
              String domain = null;
              boolean secure = false;
    
              // Parse each field
              for (int j = 1; j < fields.length; j++) {
                if ("secure".equalsIgnoreCase(fields[j])) {
                  secure = true;
                } else if (fields[j].indexOf('=') > 0) {
                  String[] f = fields[j].split("=");
                  if ("expires".equalsIgnoreCase(f[0])) {
                    expires = f[1];
                  } else if ("domain".equalsIgnoreCase(f[0])) {
                    domain = f[1];
                  } else if ("path".equalsIgnoreCase(f[0])) {
                    path = f[1];
                  }
                }
              }
    
            // Save the cookie...
    
            }
          }
    
          int responseCode = 200;
          //try {
          //responseCode = connection.getResponseCode();
          //} catch (SocketException e) {
          //  Logger.getLogger(WebOperations.class.getName()).log(Level.SEVERE, e.getMessage(), e);
          //}
          if (responseCode >= 400 && responseCode < 600) {
            return result;
          }
          String contentType = connection.getContentType();
            if (contentType == null) {
              contentType = "html";
            }
            String nameContentType=contentType.toLowerCase();
            if(nameContentType.contains("html") || nameContentType.contains("text") || nameContentType.contains("txt") || nameContentType.contains("json") || nameContentType.contains("json")) {
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String inputLine;
                while ((inputLine = in.readLine()) != null ) {
                    result.append(inputLine).append("\n");
                }
                in.close();
            }
        } catch (Exception e) {
            if(e instanceof MalformedURLException) {
                System.err.println("MalformedURLException for "+address);
            }
            //System.err.println(e.getMessage());
            Logger.getLogger(WebOperations.class.getName()).log(Level.WARNING, "Exception while reading web page", e);
        }
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-20
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      相关资源
      最近更新 更多