diff --git a/README.md b/README.md index 4d4bce9a..03ab123f 100644 --- a/README.md +++ b/README.md @@ -63,14 +63,14 @@ yum install haproxy-wi For install just clone: ``` CentOS: -$ sudo yum -y install git nmap-ncat net-tools python35u dos2unix python35u-pip mod_ssl httpd python35u-devel gcc-c++ openldap-devel python-devel python-jinja2 python35u-mod_wsgi +$ sudo yum -y install git nmap-ncat net-tools python35u dos2unix python35u-pip mod_ssl httpd python35u-devel gcc-c++ openldap-devel python-devel python-jinja2 python35u-mod_wsgi ansible $ cd /var/www/ $ git clone https://github.com/Aidaho12/haproxy-wi.git /var/www/haproxy-wi $ chown -R apache:apache haproxy-wi/ Or if use Debian/Ubuntu: -$ sudo apt-get install git net-tools lshw dos2unix apache2 gcc netcat python3.5 python3.5-mod_wsgi mod_ssl python3-pip g++ freetype2-demos libatlas-base-dev openldap-dev libpq-dev python-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev libffi-dev python3-dev libssl-dev -y +$ sudo apt-get install git net-tools lshw dos2unix apache2 gcc netcat python3.5 python3.5-mod_wsgi mod_ssl python3-pip g++ freetype2-demos libatlas-base-dev openldap-dev libpq-dev python-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev libffi-dev python3-dev libssl-dev ansible -y $ chown -R www-data:www-data haproxy-wi/ Both diff --git a/app/add.py b/app/add.py index 7bc4e32f..d5be4e13 100644 --- a/app/add.py +++ b/app/add.py @@ -69,7 +69,7 @@ if form.getvalue('mode') is not None: end_name = form.getvalue('listner') elif form.getvalue('frontend') is not None: name = "frontend " + form.getvalue('frontend') - backend = " default_backend " + form.getvalue('backend') + "\n" + backend = " default_backend " + form.getvalue('backends') + "\n" end_name = form.getvalue('frontend') elif form.getvalue('new_backend') is not None: name = "backend " + form.getvalue('new_backend') diff --git a/app/funct.py b/app/funct.py index 83948963..fb95e42d 100644 --- a/app/funct.py +++ b/app/funct.py @@ -353,7 +353,10 @@ def install_haproxy(serv, **kwargs): os.system("cp scripts/%s ." % script) - proxy_serv = proxy if proxy is not None else "" + if hapver is None: + hapver = '2.0.7-1' + + proxy_serv = proxy if proxy is not None else '' syn_flood_protect = '1' if kwargs.get('syn_flood') == "1" else '' commands = [ "chmod +x "+script +" && ./"+script +" PROXY=" + proxy_serv+ @@ -367,9 +370,17 @@ def install_haproxy(serv, **kwargs): logging('localhost', error, haproxywi=1) print('error: '+error) else: - print(output[0]) + for l in output: + if "msg" in l or "FAILED" in l: + l = l.split(':')[1] + l = l.split('"')[1] + print(l+"
") + break + else: + print('success: HAProxy was installed
') - + os.system("rm -f %s" % script) + def waf_install(serv, **kwargs): import sql @@ -412,6 +423,7 @@ def check_haproxy_version(serv): ver = line return ver + def upload(serv, path, file, **kwargs): error = "" full_path = path + file @@ -618,7 +630,6 @@ def show_backends(serv, **kwargs): back = json.dumps(line).split("\"") if kwargs.get('ret'): ret.append(back[1]) - #ret += "," else: print(back[1], end="
") @@ -676,7 +687,6 @@ def check_new_version(): res = response.content.decode(encoding='UTF-8') except requests.exceptions.RequestException as e: - #print(e) e = str(e) logging('localhost', ' '+e, haproxywi=1) diff --git a/app/options.py b/app/options.py index ec60100d..7abb1425 100644 --- a/app/options.py +++ b/app/options.py @@ -4,7 +4,6 @@ import cgi import os, sys import funct import sql -import asyncio form = cgi.FieldStorage() serv = form.getvalue('serv') @@ -123,7 +122,7 @@ if form.getvalue('ip') is not None and serv is not None: if form.getvalue('showif'): - commands = ["sudo ip link|grep 'UP' | awk '{print $2}' |awk -F':' '{print $1}'"] + commands = ["sudo ip link|grep 'UP' |grep -v 'lo'| awk '{print $2}' |awk -F':' '{print $1}'"] funct.ssh_command(serv, commands, ip="1") @@ -147,116 +146,118 @@ if form.getvalue('action_waf') is not None and serv is not None: funct.ssh_command(serv, commands) -async def async_get_overview(serv1, serv2): - server_status = () - commands2 = [ "ps ax |grep waf/bin/modsecurity |grep -v grep |wc -l" ] - cmd = 'echo "show info" |nc %s %s -w 1|grep -e "Process_num"' % (serv2, sql.get_setting('haproxy_sock_port')) - server_status = (serv1, - serv2, - funct.server_status(funct.subprocess_execute(cmd)), - sql.select_servers(server=serv2, keep_alive=1), - funct.ssh_command(serv2, commands2), - sql.select_waf_servers(serv2)) - return server_status +if act == "overview": + import asyncio + async def async_get_overview(serv1, serv2): + server_status = () + commands2 = [ "ps ax |grep waf/bin/modsecurity |grep -v grep |wc -l" ] + cmd = 'echo "show info" |nc %s %s -w 1|grep -e "Process_num"' % (serv2, sql.get_setting('haproxy_sock_port')) + server_status = (serv1, + serv2, + funct.server_status(funct.subprocess_execute(cmd)), + sql.select_servers(server=serv2, keep_alive=1), + funct.ssh_command(serv2, commands2), + sql.select_waf_servers(serv2)) + return server_status -async def get_runner_overview(): - import http.cookies - from jinja2 import Environment, FileSystemLoader - env = Environment(loader=FileSystemLoader('templates/ajax'),extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do']) - - servers = [] - template = env.get_template('overview.html') - cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) - user_id = cookie.get('uuid') - futures = [async_get_overview(server[1], server[2]) for server in sql.get_dick_permit()] - for i, future in enumerate(asyncio.as_completed(futures)): - result = await future - servers.append(result) - servers_sorted = sorted(servers, key=funct.get_key) - template = template.render(service_status=servers_sorted, role=sql.get_user_role_by_uuid(user_id.value)) - print(template) + + async def get_runner_overview(): + import http.cookies + from jinja2 import Environment, FileSystemLoader + env = Environment(loader=FileSystemLoader('templates/ajax'),extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do']) + + servers = [] + template = env.get_template('overview.html') + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + user_id = cookie.get('uuid') + futures = [async_get_overview(server[1], server[2]) for server in sql.get_dick_permit()] + for i, future in enumerate(asyncio.as_completed(futures)): + result = await future + servers.append(result) + servers_sorted = sorted(servers, key=funct.get_key) + template = template.render(service_status=servers_sorted, role=sql.get_user_role_by_uuid(user_id.value)) + print(template) -if act == "overview": ioloop = asyncio.get_event_loop() ioloop.run_until_complete(get_runner_overview()) ioloop.close() - -async def async_get_overviewWaf(serv1, serv2): - haproxy_dir = sql.get_setting('haproxy_dir') - server_status = () - commands = [ "ps ax |grep waf/bin/modsecurity |grep -v grep |wc -l" ] - commands1 = [ "cat %s/waf/modsecurity.conf |grep SecRuleEngine |grep -v '#' |awk '{print $2}'" % haproxy_dir ] - server_status = (serv1,serv2, funct.ssh_command(serv2, commands), funct.ssh_command(serv2, commands1).strip(), sql.select_waf_metrics_enable_server(serv2)) - return server_status +if act == "overviewwaf": + import asyncio + async def async_get_overviewWaf(serv1, serv2): + haproxy_dir = sql.get_setting('haproxy_dir') + server_status = () + commands = [ "ps ax |grep waf/bin/modsecurity |grep -v grep |wc -l" ] + commands1 = [ "cat %s/waf/modsecurity.conf |grep SecRuleEngine |grep -v '#' |awk '{print $2}'" % haproxy_dir ] + + server_status = (serv1,serv2, funct.ssh_command(serv2, commands), funct.ssh_command(serv2, commands1).strip(), sql.select_waf_metrics_enable_server(serv2)) + return server_status -async def get_runner_overviewWaf(url): - import http.cookies - from jinja2 import Environment, FileSystemLoader - env = Environment(loader=FileSystemLoader('templates/ajax'),extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do']) - template = env.get_template('overivewWaf.html') + async def get_runner_overviewWaf(url): + import http.cookies + from jinja2 import Environment, FileSystemLoader + env = Environment(loader=FileSystemLoader('templates/ajax'),extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do']) + template = env.get_template('overivewWaf.html') + + servers = [] + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + user_id = cookie.get('uuid') + futures = [async_get_overviewWaf(server[1], server[2]) for server in sql.get_dick_permit()] + for i, future in enumerate(asyncio.as_completed(futures)): + result = await future + servers.append(result) + servers_sorted = sorted(servers, key=funct.get_key) + template = template.render(service_status=servers_sorted, role=sql.get_user_role_by_uuid(user_id.value), url=url) + print(template) - servers = [] - cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) - user_id = cookie.get('uuid') - futures = [async_get_overviewWaf(server[1], server[2]) for server in sql.get_dick_permit()] - for i, future in enumerate(asyncio.as_completed(futures)): - result = await future - servers.append(result) - servers_sorted = sorted(servers, key=funct.get_key) - template = template.render(service_status=servers_sorted, role=sql.get_user_role_by_uuid(user_id.value), url=url) - print(template) - - -if act == "overviewwaf": ioloop = asyncio.get_event_loop() ioloop.run_until_complete(get_runner_overviewWaf(form.getvalue('page'))) ioloop.close() -async def async_get_overviewServers(serv1, serv2): - server_status = () - commands = [ "top -u haproxy -b -n 1" ] - cmd = 'echo "show info" |nc %s %s -w 1|grep -e "Ver\|CurrConns\|Maxco\|MB\|Uptime:"' % (serv2, sql.get_setting('haproxy_sock_port')) - out = funct.subprocess_execute(cmd) - out1 = "" - - for k in out: - if "Ncat:" not in k: - for r in k: - out1 += r - out1 += "
" - else: - out1 = "Can\'t connect to HAproxy" - - server_status = (serv1,serv2, out1, funct.ssh_command(serv2, commands)) - return server_status - - -async def get_runner_overviewServers(**kwargs): - import http.cookies - from jinja2 import Environment, FileSystemLoader - env = Environment(loader=FileSystemLoader('templates/ajax'),extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do']) - template = env.get_template('overviewServers.html') - - servers = [] - cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) - user_id = cookie.get('uuid') - role = sql.get_user_role_by_uuid(user_id.value) - futures = [async_get_overviewServers(kwargs.get('server1'), kwargs.get('server2'))] - - for i, future in enumerate(asyncio.as_completed(futures)): - result = await future - servers.append(result) - servers_sorted = sorted(servers, key=funct.get_key) - template = template.render(service_status=servers_sorted, role=role, id=kwargs.get('id')) - print(template) - - if act == "overviewServers": + import asyncio + async def async_get_overviewServers(serv1, serv2): + server_status = () + commands = [ "top -u haproxy -b -n 1" ] + cmd = 'echo "show info" |nc %s %s -w 1|grep -e "Ver\|CurrConns\|Maxco\|MB\|Uptime:"' % (serv2, sql.get_setting('haproxy_sock_port')) + out = funct.subprocess_execute(cmd) + out1 = "" + + for k in out: + if "Ncat:" not in k: + for r in k: + out1 += r + out1 += "
" + else: + out1 = "Can\'t connect to HAproxy" + + server_status = (serv1,serv2, out1, funct.ssh_command(serv2, commands)) + return server_status + + + async def get_runner_overviewServers(**kwargs): + import http.cookies + from jinja2 import Environment, FileSystemLoader + env = Environment(loader=FileSystemLoader('templates/ajax'),extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do']) + template = env.get_template('overviewServers.html') + + servers = [] + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + user_id = cookie.get('uuid') + role = sql.get_user_role_by_uuid(user_id.value) + futures = [async_get_overviewServers(kwargs.get('server1'), kwargs.get('server2'))] + + for i, future in enumerate(asyncio.as_completed(futures)): + result = await future + servers.append(result) + servers_sorted = sorted(servers, key=funct.get_key) + template = template.render(service_status=servers_sorted, role=role, id=kwargs.get('id')) + print(template) + id = form.getvalue('id') name = form.getvalue('name') ioloop = asyncio.get_event_loop() @@ -619,11 +620,11 @@ if form.getvalue('master'): os.system("cp scripts/%s ." % script) if form.getvalue('hap') == "1": - funct.install_haproxy(master, syn_flood='1') - funct.install_haproxy(slave, syn_flood='1') + funct.install_haproxy(master) + funct.install_haproxy(slave) commands = [ "chmod +x "+script +" && ./"+script +" PROXY=" + proxy_serv+ - " ETH="+ETH+" IP="+str(IP)+" MASTER=MASTER"+" HOST="+str(master)+ + " ETH="+ETH+" IP="+str(IP)+" MASTER=MASTER"+" SYN_FLOOD="+syn_flood+" HOST="+str(master)+ " USER="+str(ssh_user_name)+" PASS="+str(ssh_user_password)+" KEY="+str(ssh_key_name) ] output, error = funct.subprocess_execute(commands[0]) @@ -632,7 +633,20 @@ if form.getvalue('master'): logging('localhost', error, haproxywi=1) print('error: '+error) else: - print(output[0]) + for l in output: + if "msg" in l or "FAILED" in l: + l = l.split(':')[1] + l = l.split('"')[1] + print(l+"
") + break + else: + print('success: Master Keepalived was installed
') + + for sshs in sql.select_ssh(serv=slave): + ssh_enable = sshs[3] + ssh_user_name = sshs[4] + ssh_user_password = sshs[5] + ssh_key_name = fullpath+'/keys/%s.pem' % sshs[2] commands = [ "chmod +x "+script +" && ./"+script +" PROXY=" +proxy_serv+ " ETH="+ETH+" IP="+IP+" MASTER=BACKUP"+" HOST="+str(slave)+ @@ -644,31 +658,87 @@ if form.getvalue('master'): logging('localhost', error, haproxywi=1) print('error: '+error) else: - print(output[0]) + for l in output: + if "msg" in l or "FAILED" in l: + l = l.split(':')[1] + l = l.split('"')[1] + print(l+"
") + break + else: + print('success: Slave Keepalived was installed
') - #os.system("rm -f %s" % script) + os.system("rm -f %s" % script) sql.update_server_master(master, slave) if form.getvalue('masteradd'): master = form.getvalue('masteradd') slave = form.getvalue('slaveadd') - interface = form.getvalue('interfaceadd') - vrrpip = form.getvalue('vrrpipadd') + ETH = form.getvalue('interfaceadd') + IP = form.getvalue('vrrpipadd') kp = form.getvalue('kp') - tmp_config_path = sql.get_setting('tmp_config_path') - script = "add_vrrp.sh" + script = "install_keepalived.sh" + fullpath = funct.get_config_var('main', 'fullpath') + proxy = sql.get_setting('proxy') + ssh_enable = '' + ssh_port = '' + ssh_user_name = '' + ssh_user_password = '' + proxy_serv = proxy if proxy is not None else "" + + for sshs in sql.select_ssh(serv=master): + ssh_enable = sshs[3] + ssh_user_name = sshs[4] + ssh_user_password = sshs[5] + ssh_key_name = fullpath+'/keys/%s.pem' % sshs[2] + os.system("cp scripts/%s ." % script) - error = str(funct.upload(master, tmp_config_path, script)) - if error: - print('error: '+error) - sys.exit() - funct.upload(slave, tmp_config_path, script) + commands = [ "chmod +x "+script +" && ./"+script +" PROXY=" + proxy_serv+ + " ETH="+ETH+" IP="+str(IP)+" MASTER=MASTER"+" RESTART="+kp+" ADD_VRRP=1 HOST="+str(master)+ + " USER="+str(ssh_user_name)+" PASS="+str(ssh_user_password)+" KEY="+str(ssh_key_name) ] - funct.ssh_command(master, ["sudo chmod +x "+tmp_config_path+script, tmp_config_path+script+" MASTER "+interface+" "+vrrpip+" "+kp]) - funct.ssh_command(slave, ["sudo chmod +x "+tmp_config_path+script, tmp_config_path+script+" BACKUP "+interface+" "+vrrpip+" "+kp]) + output, error = funct.subprocess_execute(commands[0]) + + if error: + logging('localhost', error, haproxywi=1) + print('error: '+error) + else: + for l in output: + if "msg" in l or "FAILED" in l: + l = l.split(':')[1] + l = l.split('"')[1] + print(l+"
") + break + else: + print('success: Master VRRP address was added
') + + + for sshs in sql.select_ssh(serv=slave): + ssh_enable = sshs[3] + ssh_user_name = sshs[4] + ssh_user_password = sshs[5] + ssh_key_name = fullpath+'/keys/%s.pem' % sshs[2] + + commands = [ "chmod +x "+script +" && ./"+script +" PROXY=" + proxy_serv+ + " ETH="+ETH+" IP="+str(IP)+" MASTER=BACKUP"+" RESTART="+kp+" ADD_VRRP=1 HOST="+str(slave)+ + " USER="+str(ssh_user_name)+" PASS="+str(ssh_user_password)+" KEY="+str(ssh_key_name) ] + + output, error = funct.subprocess_execute(commands[0]) + + if error: + logging('localhost', error, haproxywi=1) + print('error: '+error) + else: + for l in output: + if "msg" in l or "FAILED" in l: + l = l.split(':')[1] + l = l.split('"')[1] + print(l+"
") + break + else: + print('success: Slave VRRP address was added
') os.system("rm -f %s" % script) diff --git a/app/scripts/add_vrrp.sh b/app/scripts/add_vrrp.sh deleted file mode 100644 index 360a04c8..00000000 --- a/app/scripts/add_vrrp.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -CONF=/etc/keepalived/keepalived.conf -IP=`sudo cat $CONF |grep $3 |sed s/' '//g|sed s/'\t'//g| head -1` -VI=`sudo cat /etc/keepalived/keepalived.conf |grep VI |awk '{print $2}' |awk -F"_" '{print $2}' |tail -1` -VI=$(($VI+1)) - -if [[ $IP == $3 ]];then - echo -e "error: VRRP address alredy use" - exit 1 -fi - -sudo bash -c cat << EOF >> $CONF -vrrp_instance VI_$VI { - state MASTER - interface eth1 - virtual_router_id 101 - priority 103 - - #check if we are still running - track_script { - chk_haproxy - } - - advert_int 1 - authentication { - auth_type PASS - auth_pass VerySecretPass2! - } - virtual_ipaddress { - 0.0.0.1 - } - -} -EOF -if [ $? -eq 1 ] -then - echo "Can't read keepalived config" - exit 1 -fi -sudo sed -i "s/MASTER/$1/g" $CONF -sudo sed -i "s/eth1/$2/g" $CONF -sudo sed -i "s/0.0.0.1/$3/g" $CONF - -if [[ $1 == "BACKUP" ]];then - sudo sed -i "s/103/104/g" $CONF -fi - -if [[ $4 == "1" ]];then - sudo systemctl restart keepalived -fi -echo "success" \ No newline at end of file diff --git a/app/scripts/ansible/roles/haproxy/tasks/main.yml b/app/scripts/ansible/roles/haproxy/tasks/main.yml index 42e91239..3d3a73d2 100644 --- a/app/scripts/ansible/roles/haproxy/tasks/main.yml +++ b/app/scripts/ansible/roles/haproxy/tasks/main.yml @@ -1,11 +1,26 @@ --- +- name: check if HAProxy is installed + yum: + list=haproxy + register: is_installed + +- name: HAProxy has already installed + debug: + msg: "HAProxy has already installed" + when: is_installed.results|selectattr("yumstate", "match", "installed")|list|length != 0 + +- name: Exiting + meta: end_play + when: is_installed.results|selectattr("yumstate", "match", "installed")|list|length != 0 + - name: install HAProxy {{HAPVER}} yum: name: - http://repo.haproxy-wi.org/haproxy-{{HAPVER}}.el6.x86_64.rpm - socat state: present - when: (ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') and ansible_facts['distribution_major_version']|int == 6 + when: (ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') and ansible_facts['distribution_major_version']|int == 6 and HAPVER|length > 0 + register: install_result environment: http_proxy: "{{PROXY}}" https_proxy: "{{PROXY}}" @@ -17,7 +32,7 @@ - http://repo.haproxy-wi.org/haproxy-{{HAPVER}}.el7.x86_64.rpm - socat state: present - when: (ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') and ansible_facts['distribution_major_version']|int == 7 + when: ((ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') and ansible_facts['distribution_major_version']|int == 7) and HAPVER|length > 0 environment: http_proxy: "{{PROXY}}" https_proxy: "{{PROXY}}" @@ -26,7 +41,7 @@ - name: set_fact from wi` set_fact: haproxy_from_wi: "yes" - when: (ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') and ansible_facts['distribution_major_version']|int == 7 + when: (ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') and ansible_facts['distribution_major_version']|int == 7 and HAPVER|length > 0 - name: install the latest version of HAProxy @@ -35,7 +50,7 @@ - haproxy - socat state: latest - when: (ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') and ansible_facts['distribution_major_version']|int != 7 + when: ((ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') and ansible_facts['distribution_major_version']|int != 7) or ("'FAILED' in install_result.stderr") environment: http_proxy: "{{PROXY}}" https_proxy: "{{PROXY}}" @@ -81,48 +96,15 @@ - name: Enable and start service HAProxy - service: + systemd: name: haproxy daemon_reload: yes state: started enabled: yes + force: no ignore_errors: yes -- name: Enable net.ipv4.tcp_syncookies - sysctl: - name: net.ipv4.tcp_syncookies - value: '1' - sysctl_set: yes - state: present - reload: yes - when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) - - -- name: net.ipv4.conf.all.rp_filter - sysctl: - name: net.ipv4.conf.all.rp_filter - value: '1' - sysctl_set: yes - state: present - reload: yes - when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) - -- name: Enable net.ipv4.tcp_max_syn_backlog - sysctl: - name: net.ipv4.tcp_max_syn_backlog - value: '1024' - sysctl_set: yes - state: present - reload: yes - when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) - -- name: Enable net.ipv4.tcp_synack_retries - sysctl: - name: net.ipv4.tcp_synack_retries - value: '3' - sysctl_set: yes - state: present - reload: yes - when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) - +- name: Add syn_flood tasks + include: syn_flood.yml + when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) \ No newline at end of file diff --git a/app/scripts/ansible/roles/haproxy/tasks/syn_flood.yml b/app/scripts/ansible/roles/haproxy/tasks/syn_flood.yml new file mode 100644 index 00000000..9f58e013 --- /dev/null +++ b/app/scripts/ansible/roles/haproxy/tasks/syn_flood.yml @@ -0,0 +1,36 @@ +- name: Enable net.ipv4.tcp_syncookies + sysctl: + name: net.ipv4.tcp_syncookies + value: '1' + sysctl_set: yes + state: present + reload: yes + when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) + + +- name: net.ipv4.conf.all.rp_filter + sysctl: + name: net.ipv4.conf.all.rp_filter + value: '1' + sysctl_set: yes + state: present + reload: yes + when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) + +- name: Enable net.ipv4.tcp_max_syn_backlog + sysctl: + name: net.ipv4.tcp_max_syn_backlog + value: '1024' + sysctl_set: yes + state: present + reload: yes + when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) + +- name: Enable net.ipv4.tcp_synack_retries + sysctl: + name: net.ipv4.tcp_synack_retries + value: '3' + sysctl_set: yes + state: present + reload: yes + when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) \ No newline at end of file diff --git a/app/scripts/ansible/roles/haproxy/templates/haproxy.service.j2 b/app/scripts/ansible/roles/haproxy/templates/haproxy.service.j2 index 0a4fc76c..3424a19a 100644 --- a/app/scripts/ansible/roles/haproxy/templates/haproxy.service.j2 +++ b/app/scripts/ansible/roles/haproxy/templates/haproxy.service.j2 @@ -6,9 +6,9 @@ After=network.target EnvironmentFile=-/etc/default/haproxy EnvironmentFile=-/etc/sysconfig/haproxy Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "EXTRAOPTS=-S /run/haproxy-master.sock" -ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS -ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS -ExecReload=/usr/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS +ExecStartPre=/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS +ExecStart=/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS +ExecReload=/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS ExecReload=/bin/kill -USR2 $MAINPID KillMode=mixed Restart=always diff --git a/app/scripts/ansible/roles/keepalived/tasks/add_vrrp.yml b/app/scripts/ansible/roles/keepalived/tasks/add_vrrp.yml new file mode 100644 index 00000000..be902672 --- /dev/null +++ b/app/scripts/ansible/roles/keepalived/tasks/add_vrrp.yml @@ -0,0 +1,28 @@ +--- +- name: Creation config from template + template: + src: add_vrrp.conf.j2 + dest: /etc/keepalived/keepalived.conf_temp + mode: 0644 + force: no + + +- name: "Append keepalived.conf with content from temporary file" + shell: cat keepalived.conf_temp >> keepalived.conf + args: + chdir: "/etc/keepalived/" + + +- name: "Delete temporary file" + file: + path: /etc/keepalived/keepalived.conf_temp + state: absent + + +- name: Restart service keepalived + service: + name: keepalived + state: restarted + force: no + ignore_errors: yes + when: (RESTART is defined) and (RESTART|length > 0) \ No newline at end of file diff --git a/app/scripts/ansible/roles/keepalived/tasks/install.yml b/app/scripts/ansible/roles/keepalived/tasks/install.yml new file mode 100644 index 00000000..5507ccfa --- /dev/null +++ b/app/scripts/ansible/roles/keepalived/tasks/install.yml @@ -0,0 +1,67 @@ +--- +- name: check if Keepalived is installed + yum: + list=keepalived + register: is_installed + +- name: Keepalived has already installed + debug: + msg: "Keepalived has already installed" + when: is_installed.results|selectattr("yumstate", "match", "installed")|list|length != 0 + +- name: Exiting + meta: end_play + when: is_installed.results|selectattr("yumstate", "match", "installed")|list|length != 0 + + +- name: install the latest version of Keepalived + yum: + name: + - keepalived + state: latest + when: (ansible_facts['os_family'] == "RedHat") or (ansible_facts['os_family'] == 'CentOS') + environment: + http_proxy: "{{PROXY}}" + https_proxy: "{{PROXY}}" + + +- name: Install keepalived + apt: + name: + - keepalived + state: present + when: (ansible_facts['os_family'] == 'Debian') or (ansible_facts['os_family'] == 'Ubuntu') + environment: + http_proxy: "{{PROXY}}" + https_proxy: "{{PROXY}}" + + +- name: Copy keepalived configuration in place. + template: + src: keepalived.conf.j2 + dest: /etc/keepalived/keepalived.conf + mode: 0644 + notify: restart keepalived + + +- name: Enable and start service keepalived + service: + name: keepalived + daemon_reload: yes + state: started + enabled: yes + ignore_errors: yes + + +- name: Enable net.ipv4.ip_forward + sysctl: + name: net.ipv4.ip_forward + value: '1' + sysctl_set: yes + state: present + reload: yes + + +- name: Add syn_flood tasks + include: ../../haproxy/tasks/syn_flood.yml + when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0) \ No newline at end of file diff --git a/app/scripts/ansible/roles/keepalived/tasks/main.yml b/app/scripts/ansible/roles/keepalived/tasks/main.yml index 01059d5b..8117a8e5 100644 --- a/app/scripts/ansible/roles/keepalived/tasks/main.yml +++ b/app/scripts/ansible/roles/keepalived/tasks/main.yml @@ -1,39 +1,9 @@ ---- -- name: install the latest version of Keepalived - yum: - name: - - keepalived - state: latest - when: ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS' - environment: - http_proxy: "{{PROXY}}" - https_proxy: "{{PROXY}}" - - -- name: Install keepalived - apt: - name: - - keepalived - state: present - when: ansible_facts['os_family'] == 'Debian' or ansible_facts['os_family'] == 'Ubuntu' - environment: - http_proxy: "{{PROXY}}" - https_proxy: "{{PROXY}}" - - -- name: Copy keepalived configuration in place. - template: - src: keepalived.conf.j2 - dest: /etc/keepalived/keepalived.conf - mode: 0644 - notify: restart keepalived +--- +- name: Add installation tasks + include: install.yml + when: (ADD_VRRP is not defined) or (ADD_VRRP != "1") -- name: Enable and start service keepalived - service: - name: keepalived - daemon_reload: yes - state: started - enabled: yes - ignore_errors: yes - \ No newline at end of file +- name: Add add vrrp tasks + include: add_vrrp.yml + when: (ADD_VRRP is defined) and (ADD_VRRP|length > 0) \ No newline at end of file diff --git a/app/scripts/ansible/roles/keepalived/templates/add_vrrp.conf.j2 b/app/scripts/ansible/roles/keepalived/templates/add_vrrp.conf.j2 new file mode 100644 index 00000000..0b1f68e8 --- /dev/null +++ b/app/scripts/ansible/roles/keepalived/templates/add_vrrp.conf.j2 @@ -0,0 +1,25 @@ +{% if MASTER == 'BACKUP' %} + {% set ID = '101' %} +{% else %} + {% set ID = '100' %} +{% endif %} + +vrrp_instance VI_{{ID}} { + state {{MASTER}} + interface {{ETH}} + virtual_router_id 101 + priority 103 + + track_script { + chk_haproxy + } + + advert_int 1 + authentication { + auth_type PASS + auth_pass VerySecretPass2! + } + virtual_ipaddress { + {{IP}} + } +} \ No newline at end of file diff --git a/app/scripts/ansible/roles/keepalived/templates/keepalived.conf.j2 b/app/scripts/ansible/roles/keepalived/templates/keepalived.conf.j2 index 001f7a66..2f770f58 100644 --- a/app/scripts/ansible/roles/keepalived/templates/keepalived.conf.j2 +++ b/app/scripts/ansible/roles/keepalived/templates/keepalived.conf.j2 @@ -26,4 +26,4 @@ vrrp_instance VI_1 { virtual_ipaddress { {{IP}} } -} \ No newline at end of file +} diff --git a/app/scripts/install_haproxy.sh b/app/scripts/install_haproxy.sh index a5f9726f..58183623 100644 --- a/app/scripts/install_haproxy.sh +++ b/app/scripts/install_haproxy.sh @@ -1,5 +1,4 @@ #!/bin/bash - for ARGUMENT in "$@" do KEY=$(echo $ARGUMENT | cut -f1 -d=) @@ -21,21 +20,22 @@ do *) esac done + export ANSIBLE_HOST_KEY_CHECKING=False +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False PWD=`pwd` PWD=$PWD/scripts/ansible/ echo $HOST > $PWD/$HOST if [[ $KEY == "" ]]; then - ansible-playbook $PWD/roles/haproxy.yml -e "ansible_user=$USER ansible_ssh_pass=$PASS variable_host=$HOST PROXY=$PROXY HAPVER=$HAPVER SOCK_PORT=$SOCK_PORT STAT_PORT=$STAT_PORT STATS_USER=$STATS_USER STATS_PASS=$STATS_PASS $STAT_FILE=$STAT_FILE SYN_FLOOD=$SYN_FLOOD" -i $PWD/$HOST > /tmp/install_haproxy.log + ansible-playbook $PWD/roles/haproxy.yml -e "ansible_user=$USER ansible_ssh_pass=$PASS variable_host=$HOST PROXY=$PROXY HAPVER=$HAPVER SOCK_PORT=$SOCK_PORT STAT_PORT=$STAT_PORT STATS_USER=$STATS_USER STATS_PASS=$STATS_PASS $STAT_FILE=$STAT_FILE SYN_FLOOD=$SYN_FLOOD" -i $PWD/$HOST else - ansible-playbook $PWD/roles/haproxy.yml --key-file $KEY -e "ansible_user=$USER variable_host=$HOST PROXY=$PROXY HAPVER=$HAPVER SOCK_PORT=$SOCK_PORT STAT_PORT=$STAT_PORT STATS_USER=$STATS_USER STATS_PASS=$STATS_PASS STAT_FILE=$STAT_FILE SYN_FLOOD=$SYN_FLOOD" -i $PWD/$HOST > /tmp/install_haproxy.log + ansible-playbook $PWD/roles/haproxy.yml --key-file $KEY -e "ansible_user=$USER variable_host=$HOST PROXY=$PROXY HAPVER=$HAPVER SOCK_PORT=$SOCK_PORT STAT_PORT=$STAT_PORT STATS_USER=$STATS_USER STATS_PASS=$STATS_PASS STAT_FILE=$STAT_FILE SYN_FLOOD=$SYN_FLOOD" -i $PWD/$HOST fi -if [ $? -eq 1 ] +if [ $? -gt 0 ] then - echo "error: Can't install Haproxy service. Look log in the /tmp/install_haproxy.log

" + echo "error: Can't install Haproxy service

" exit 1 fi -echo "success" rm -f $PWD/$HOST diff --git a/app/scripts/install_keepalived.sh b/app/scripts/install_keepalived.sh index 3cb17090..4b5cd06a 100644 --- a/app/scripts/install_keepalived.sh +++ b/app/scripts/install_keepalived.sh @@ -1,5 +1,4 @@ #!/bin/bash - for ARGUMENT in "$@" do KEY=$(echo $ARGUMENT | cut -f1 -d=) @@ -14,25 +13,28 @@ do USER) USER=${VALUE} ;; PASS) PASS=${VALUE} ;; KEY) KEY=${VALUE} ;; + SYN_FLOOD) SYN_FLOOD=${VALUE} ;; + RESTART) RESTART=${VALUE} ;; + ADD_VRRP) ADD_VRRP=${VALUE} ;; *) esac done export ANSIBLE_HOST_KEY_CHECKING=False +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False PWD=`pwd` PWD=$PWD/scripts/ansible/ echo $HOST > $PWD/$HOST if [[ $KEY == "" ]]; then - ansible-playbook $PWD/roles/keepalived.yml -e "ansible_user=$USER ansible_ssh_pass=$PASS variable_host=$HOST PROXY=$PROXY MASTER=$MASTER ETH=$ETH IP=$IP" -i $PWD/$HOST > /tmp/install_keepalived.log + ansible-playbook $PWD/roles/keepalived.yml -e "ansible_user=$USER ansible_ssh_pass=$PASS variable_host=$HOST SYN_FLOOD=$SYN_FLOOD PROXY=$PROXY MASTER=$MASTER ETH=$ETH IP=$IP RESTART=$RESTART ADD_VRRP=$ADD_VRRP" -i $PWD/$HOST else - ansible-playbook $PWD/roles/keepalived.yml --key-file $KEY -e "ansible_user=$USER variable_host=$HOST PROXY=$PROXY MASTER=$MASTER ETH=$ETH IP=$IP" -i $PWD/$HOST > /tmp/install_keepalived.log + ansible-playbook $PWD/roles/keepalived.yml --key-file $KEY -e "ansible_user=$USER variable_host=$HOST SYN_FLOOD=$SYN_FLOOD PROXY=$PROXY MASTER=$MASTER ETH=$ETH IP=$IP RESTART=$RESTART ADD_VRRP=$ADD_VRRP" -i $PWD/$HOST fi -if [ $? -eq 1 ] +if [ $? -gt 0 ] then - echo "error: Can't install keepalived service. Look log in the /tmp/install_keepalived.log

" + echo "error: Can't install keepalived service

" exit 1 fi -echo "success" rm -f $PWD/$HOST \ No newline at end of file diff --git a/app/sql.py b/app/sql.py index c46b721d..8ce96558 100644 --- a/app/sql.py +++ b/app/sql.py @@ -894,7 +894,7 @@ def select_waf_servers_metrics(uuid, **kwargs): def select_waf_metrics(serv, **kwargs): con, cur = create_db.get_cur() - sql = """ select * from (select * from waf_metrics where serv = '%s' order by `date` desc limit 30) order by `date`""" % serv + sql = """ select * from (select * from waf_metrics where serv = '%s' order by `date` desc limit 60) order by `date`""" % serv try: cur.execute(sql) except sqltool.Error as e: @@ -987,7 +987,7 @@ def delete_mentrics(): def select_metrics(serv, **kwargs): con, cur = create_db.get_cur() - sql = """ select * from (select * from metrics where serv = '%s' order by `date` desc limit 30) order by `date` """ % serv + sql = """ select * from (select * from metrics where serv = '%s' order by `date` desc limit 60) order by `date` """ % serv try: cur.execute(sql) except sqltool.Error as e: diff --git a/app/templates/config.html b/app/templates/config.html index d831d2e6..c16ed250 100644 --- a/app/templates/config.html +++ b/app/templates/config.html @@ -58,10 +58,14 @@

+ {% if not keepalived %} + {% endif %} + {% if not keepalived %} + {% endif %}

{% if note %} diff --git a/app/templates/ha.html b/app/templates/ha.html index 6a19d2c3..0cfc3604 100644 --- a/app/templates/ha.html +++ b/app/templates/ha.html @@ -7,9 +7,9 @@ Master Slave - VRRP interface + Interface(?) VRRP IP - Install HAProxy(?) + HAProxy(?) SYN flood protect @@ -30,8 +30,8 @@ {% endfor %} - {{ input('interface') }} - {{ input('vrrp-ip') }} + {{ input('interface', size='7') }} + {{ input('vrrp-ip', size='14') }} {{ checkbox('hap') }} {{ checkbox('syn_flood') }} @@ -45,10 +45,10 @@ Master Slave - VRRP interface + Interface(?) VRRP IP - Restart Keepalived(?) - + Restart(?) + @@ -68,8 +68,8 @@ {% endfor %} - {{ input('interface-add') }} - {{ input('vrrp-ip-add') }} + {{ input('interface-add', size='7') }} + {{ input('vrrp-ip-add', size='14') }} {{ checkbox('kp') }} @@ -78,4 +78,11 @@
+ {% endblock %} \ No newline at end of file diff --git a/inc/add.js b/inc/add.js index f2853b6d..47707b21 100644 --- a/inc/add.js +++ b/inc/add.js @@ -737,42 +737,6 @@ $( function() { autoFocus: true, minLength: -1 }); - $( "#interface" ).autocomplete({ - source: function( request, response ) { - $.ajax( { - url: "options.py", - data: { - showif:1, - serv: $("#master").val(), - token: $('#token').val() - }, - success: function( data ) { - data = data.replace(/\s+/g,' '); - response(data.split(" ")); - } - } ); - }, - autoFocus: true, - minLength: -1 - }); - $( "#interface-add" ).autocomplete({ - source: function( request, response ) { - $.ajax( { - url: "options.py", - data: { - showif:1, - serv: $("#master-add").val(), - token: $('#token').val() - }, - success: function( data ) { - data = data.replace(/\s+/g,' '); - response(data.split(" ")); - } - } ); - }, - autoFocus: true, - minLength: -1 - }); $( "#ssl_key_upload" ).click(function() { $('.alert-danger').remove(); $.ajax( { diff --git a/inc/users.js b/inc/users.js index 0a17923b..9771e254 100644 --- a/inc/users.js +++ b/inc/users.js @@ -14,6 +14,42 @@ jQuery.expr[':'].regex = function(elem, index, match) { } $( function() { + $( "#interface" ).autocomplete({ + source: function( request, response ) { + $.ajax( { + url: "options.py", + data: { + showif:1, + serv: $("#master").val(), + token: $('#token').val() + }, + success: function( data ) { + data = data.replace(/\s+/g,' '); + response(data.split(" ")); + } + } ); + }, + autoFocus: true, + minLength: -1 + }); + $( "#interface-add" ).autocomplete({ + source: function( request, response ) { + $.ajax( { + url: "options.py", + data: { + showif:1, + serv: $("#master-add").val(), + token: $('#token').val() + }, + success: function( data ) { + data = data.replace(/\s+/g,' '); + response(data.split(" ")); + } + } ); + }, + autoFocus: true, + minLength: -1 + }); var ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; $('#create').click(function() { var hap = 0; @@ -48,14 +84,18 @@ $( function() { type: "GET", success: function( data ) { data = data.replace(/\s+/g,' '); - if (data.indexOf('error') != '-1' || data.indexOf('alert') != '-1' || data.indexOf('Failed') != '-1') { + if (data.indexOf('error') != '-1' || data.indexOf('alert') != '-1' || data.indexOf('FAILED') != '-1') { $("#ajax").html('
'+data+''); } else if (data.indexOf('info') != '-1' ){ $("#ajax").html('
'+data+''); } else if (data.indexOf('success') != '-1' ){ $('.alert-danger').remove(); - $("#ajax").html('
All is ready!'); - } + $("#ajax").html('
'+data+''); + } else { + $('.alert-danger').remove(); + $('.alert-warning').remove(); + $("#ajax").html('
'+data+''); + } } } ); } @@ -92,8 +132,12 @@ $( function() { $("#ajax").html('
'+data+''); } else if (data.indexOf('success') != '-1'){ $('.alert-danger').remove(); - $("#ajax").html('
All is ready!'); - } + $("#ajax").html('
'+data+''); + } else { + $('.alert-danger').remove(); + $('.alert-warning').remove(); + $("#ajax").html('
'+data+''); + } } } ); } @@ -116,7 +160,7 @@ $( function() { type: "GET", success: function( data ) { data = data.replace(/\s+/g,' '); - if (data.indexOf('error') != '-1' || data.indexOf('Failed') != '-1') { + if (data.indexOf('error') != '-1' || data.indexOf('FAILED') != '-1') { $("#ajax").html('
'+data+''); } else if (data.indexOf('success') != '-1' ){ $('.alert-danger').remove(); @@ -126,6 +170,10 @@ $( function() { $('.alert-danger').remove(); $('.alert-warning').remove(); $("#ajax").html('
'+data+''); + } else { + $('.alert-danger').remove(); + $('.alert-warning').remove(); + $("#ajax").html('
'+data+''); } } } );