diff --git a/app/create_db.py b/app/create_db.py index 5027048e..8410210d 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -632,6 +632,36 @@ def update_db_v_4_4_2_1(**kwargs): con.close() +def update_db_v_4_3_2_1(**kwargs): + con, cur = get_cur() + groups = '' + sql = """ select id from `groups` """ + try: + cur.execute(sql) + except sqltool.Error as e: + funct.out_error(e) + else: + groups = cur.fetchall() + + for g in groups: + sql = """ + INSERT INTO settings (param, value, section, `desc`, `group`) values('haproxy_enterprise', '0', 'haproxy', 'Use this option, if your HAProxy is enterprise. It change service name for rebooting/reloading', '%s'); + """ % g[0] + try: + cur.execute(sql) + con.commit() + except sqltool.Error as e: + if kwargs.get('silent') != 1: + if e.args[0] == 'columns param, group are not unique' or e == " 1060 (42S21): columns param, group are not unique ": + print('Updating... groups') + else: + print("An error occurred:", e) + else: + print("Updating... groups") + cur.close() + con.close() + + def update_db_v_4_5(**kwargs): con, cur = get_cur() sql = """CREATE TABLE IF NOT EXISTS `alerts` (`id` INTEGER NOT NULL, @@ -661,7 +691,7 @@ def update_db_v_4_5(**kwargs): def update_ver(**kwargs): con, cur = get_cur() - sql = """update version set version = '4.4.3.0'; """ + sql = """update version set version = '4.5.0.0'; """ try: cur.execute(sql) con.commit() @@ -693,6 +723,7 @@ def update_all(): update_db_v_4_4() update_db_v_4_4_2() update_db_v_4_4_2_1() + update_db_v_4_3_2_1() update_db_v_4_5() update_ver() @@ -719,6 +750,7 @@ def update_all_silent(): update_db_v_4_4(silent=1) update_db_v_4_4_2(silent=1) update_db_v_4_4_2_1(silent=1) + update_db_v_4_3_2_1(silent=1) update_db_v_4_5(silent=1) update_ver() diff --git a/app/funct.py b/app/funct.py index ea9e668b..01ce730b 100644 --- a/app/funct.py +++ b/app/funct.py @@ -708,14 +708,21 @@ def upload_and_restart(serv, cfg, **kwargs): if sql.get_setting('firewall_enable') == "1": commands[0] += open_port_firewalld(cfg, serv=serv, service='nginx') else: - if kwargs.get("just_save") == "test": - commands = [ "sudo haproxy -q -c -f " + tmp_file + " && sudo rm -f " + tmp_file ] - elif kwargs.get("just_save") == "save": - commands = [ "sudo haproxy -q -c -f " + tmp_file + " && sudo mv -f " + tmp_file + " " + config_path ] - elif kwargs.get("just_save") == "reload": - commands = [ "sudo haproxy -q -c -f " + tmp_file + " && sudo mv -f " + tmp_file + " " + config_path + " && sudo systemctl reload haproxy" ] + haproxy_enterprise = sql.get_setting('haproxy_enterprise') + + if haproxy_enterprise: + haproxy_service_name = "hapee-2.0-lb" else: - commands = [ "sudo haproxy -q -c -f " + tmp_file + " && sudo mv -f " + tmp_file + " " + config_path + " && sudo systemctl restart haproxy" ] + haproxy_service_name = "haproxy" + + if kwargs.get("just_save") == "test": + commands = [ "sudo "+haproxy_service_name+" -q -c -f " + tmp_file + " && sudo rm -f " + tmp_file ] + elif kwargs.get("just_save") == "save": + commands = [ "sudo "+haproxy_service_name+" -q -c -f " + tmp_file + " && sudo mv -f " + tmp_file + " " + config_path ] + elif kwargs.get("just_save") == "reload": + commands = [ "sudo "+haproxy_service_name+" -q -c -f " + tmp_file + " && sudo mv -f " + tmp_file + " " + config_path + " && sudo systemctl reload "+haproxy_service_name+"" ] + else: + commands = [ "sudo "+haproxy_service_name+" -q -c -f " + tmp_file + " && sudo mv -f " + tmp_file + " " + config_path + " && sudo systemctl restart "+haproxy_service_name+"" ] if sql.get_setting('firewall_enable') == "1": commands[0] += open_port_firewalld(cfg, serv=serv) error += str(upload(serv, tmp_file, cfg, dir='fullpath')) @@ -894,9 +901,9 @@ def show_haproxy_log(serv, rows=10, waf='0', grep=None, hour='00', minut='00', h sys.exit() if serv == 'backup.log': - cmd="cat %s| awk '$2>\"%s:00\" && $2<\"%s:00\"' |tail -%s %s %s %s" % (log_path + serv, date, date1, rows, user_grep, grep_act, exgrep_act) + cmd="cat %s| awk '$2>\"%s:00\" && $2<\"%s:00\"' %s %s %s |tail -%s" % (log_path + serv, date, date1, user_grep, grep_act, exgrep_act, rows) else: - cmd="cat %s| awk '$3>\"%s:00\" && $3<\"%s:00\"' |tail -%s %s %s %s" % (log_path + serv, date, date1, rows, user_grep, grep_act, exgrep_act) + cmd="cat %s| awk '$3>\"%s:00\" && $3<\"%s:00\"' %s %s %s |tail -%s" % (log_path + serv, date, date1, user_grep, grep_act, exgrep_act, rows) output, stderr = subprocess_execute(cmd) diff --git a/app/options.py b/app/options.py index 55ac8db9..90d03b68 100644 --- a/app/options.py +++ b/app/options.py @@ -333,6 +333,50 @@ if form.getvalue('list_ip_for_add') is not None: print('error: ' + stderr[0]) +if form.getvalue('sessions_select') is not None: + from jinja2 import Environment, FileSystemLoader + env = Environment(loader=FileSystemLoader('templates/ajax'), autoescape=True,extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do'], trim_blocks=True, lstrip_blocks=True) + serv = form.getvalue('sessions_select') + haproxy_sock_port = sql.get_setting('haproxy_sock_port') + + cmd = 'echo "show sess" |nc %s %s' % (serv, haproxy_sock_port) + output, stderr = funct.subprocess_execute(cmd) + + template = env.get_template('/sessions_table.html') + template = template.render(sessions=output) + + print(template) + + +if form.getvalue('sessions_select_show') is not None: + serv = form.getvalue('sessions_select_show') + sess_id = form.getvalue('sessions_select_id') + haproxy_sock_port = sql.get_setting('haproxy_sock_port') + + cmd = 'echo "show sess %s" |nc %s %s' % (sess_id, serv, haproxy_sock_port) + output, stderr = funct.subprocess_execute(cmd) + + output, stderr = funct.subprocess_execute(cmd) + + if stderr: + print('error: ' + stderr[0]) + else: + for o in output: + print(o+'
') + + +if form.getvalue('session_delete_id') is not None: + haproxy_sock_port = sql.get_setting('haproxy_sock_port') + sess_id = form.getvalue('session_delete_id') + + cmd='echo "shutdown session %s" |nc %s %s' % (sess_id, serv, haproxy_sock_port) + output, stderr = funct.subprocess_execute(cmd) + if output[0] != '': + print('error: ' + output[0]) + if stderr[0] != '': + print('error: ' + stderr[0]) + + if form.getvalue("change_pos") is not None: pos = form.getvalue('change_pos') sql.update_server_pos(pos, serv) @@ -352,10 +396,16 @@ if form.getvalue('action_hap') is not None and serv is not None: action = form.getvalue('action_hap') if funct.check_haproxy_config(serv): - commands = [ "sudo systemctl %s haproxy" % action ] + haproxy_enterprise = sql.get_setting('haproxy_enterprise') + if haproxy_enterprise: + haproxy_service_name = "hapee-2.0-lb" + else: + haproxy_service_name = "haproxy" + + commands = ["sudo systemctl %s %s" % (action, haproxy_service_name)] funct.ssh_command(serv, commands) funct.logging(serv, 'HAProxy was '+action+'ed', haproxywi=1, login=1) - print("success: HAproxy was %s" % action) + print("success: HAProxy was %s" % action) else: print("error: Bad config, check please") @@ -1492,10 +1542,17 @@ if form.getvalue('bwlists_save'): funct.logging(serv, 'has edited '+color+' list '+bwlists_save, haproxywi=1, login=1) except: pass + + haproxy_enterprise = sql.get_setting('haproxy_enterprise') + if haproxy_enterprise: + haproxy_service_name = "hapee-2.0-lb" + else: + haproxy_service_name = "haproxy" + if form.getvalue('bwlists_restart') == 'restart': - funct.ssh_command(serv, ["sudo systemctl restart haproxy"]) + funct.ssh_command(serv, ["sudo systemctl restart "+haproxy_service_name]) elif form.getvalue('bwlists_restart') == 'reload': - funct.ssh_command(serv, ["sudo systemctl reload haproxy"]) + funct.ssh_command(serv, ["sudo systemctl reload "+haproxy_service_name]) if form.getvalue('get_lists'): @@ -2071,3 +2128,52 @@ if form.getvalue('waf_rule_id'): print(funct.ssh_command(serv, cmd)) sql.update_enable_waf_rules(rule_id, serv, enable) + + +if form.getvalue('lets_domain'): + serv = form.getvalue('serv') + lets_domain = form.getvalue('lets_domain') + lets_email = form.getvalue('lets_email') + proxy = sql.get_setting('proxy') + ssl_path = sql.get_setting('cert_path') + script = "letsencrypt.sh" + ssh_enable, ssh_user_name, ssh_user_password, ssh_key_name = funct.return_ssh_keys_path(serv) + + if ssh_enable == 0: + ssh_key_name = '' + + servers = sql.select_servers(server=serv) + for server in servers: + ssh_port = str(server[10]) + + os.system("cp scripts/%s ." % script) + + if proxy is not None and proxy != '' and proxy != 'None': + proxy_serv = proxy + else: + proxy_serv = '' + + commands = ["chmod +x "+script +" && ./"+script +" PROXY=" + proxy_serv+ + " DOMAIN="+lets_domain+" EMAIL="+lets_email+" SSH_PORT="+ssh_port+" SSL_PATH="+ssl_path+ + " HOST="+serv+" USER="+ssh_user_name+" PASS="+ssh_user_password+" KEY="+ssh_key_name] + + output, error = funct.subprocess_execute(commands[0]) + + if error: + funct.logging('localhost', error, haproxywi=1) + print(error) + else: + for l in output: + if "msg" in l or "FAILED" in l: + try: + l = l.split(':')[1] + l = l.split('"')[1] + print(l+"
") + break + except: + print(output) + break + else: + print('success: Certificate has been created') + + os.system("rm -f %s" % script) \ No newline at end of file diff --git a/app/scripts/ansible/roles/letsencrypt.yml b/app/scripts/ansible/roles/letsencrypt.yml new file mode 100644 index 00000000..a6a71466 --- /dev/null +++ b/app/scripts/ansible/roles/letsencrypt.yml @@ -0,0 +1,48 @@ +- hosts: "{{ variable_host }}" + become: yes + become_method: sudo + tasks: + + - name: install EPEL Repository + yum: + name: epel-release + state: latest + when: (ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS') + ignore_errors: yes + failed_when: false + no_log: True + environment: + http_proxy: "{{PROXY}}" + https_proxy: "{{PROXY}}" + + - name: Install certbot + package: + name: certbot + state: present + environment: + http_proxy: "{{PROXY}}" + https_proxy: "{{PROXY}}" + + - name: Kill cerbot standalone + shell: ps ax |grep 'certbot certonly --standalone' |grep -v grep |awk '{print $1}' |xargs kill + ignore_errors: yes + failed_when: false + no_log: True + +# - name: Get cert +# command: certbot certonly --standalone -d "{{DOMAIN}}" --non-interactive --agree-tos --email "{{EMAIL}}" --http-01-port=8888 + + - name: Combine into pem file + shell: cat /etc/letsencrypt/live/"{{DOMAIN}}"/fullchain.pem /etc/letsencrypt/live/"{{DOMAIN}}"/privkey.pem > "{{SSL_PATH}}"/"{{DOMAIN}}".pem + + - name: Copy renew script + template: + src: /var/www/haproxy-wi/app/scripts/ansible/roles/renew_letsencrypt.j2 + dest: /etc/haproxy/renew_letsencrypt.sh + mode: '0755' + + - name: Creates cron jobs + cron: + name: "Let's encrypt renew script" + special_time: "monthly" + job: '/etc/haproxy/renew_letsencrypt.sh' \ No newline at end of file diff --git a/app/scripts/ansible/roles/renew_letsencrypt.j2 b/app/scripts/ansible/roles/renew_letsencrypt.j2 new file mode 100644 index 00000000..0ef39e10 --- /dev/null +++ b/app/scripts/ansible/roles/renew_letsencrypt.j2 @@ -0,0 +1,24 @@ +#!/bin/bash + +cd /etc/letsencrypt/live/ +email='{{EMAIL}}' +path='{{SSL_PATH}}' + +ps ax |grep 'certbot certonly --standalone' |grep -v grep |awk '{print $1}' |xargs kill + +command='sudo certbot certonly --standalone' + +for i in $(ls -d */ |awk -F"/" '{print $1}'); do + echo $i + command+=" -d "$i +done + +command+=' --non-interactive --agree-tos --email $email --http-01-port=8888' + +for i in $(ls -d */ |awk -F"/" '{print $1}'); do + bash -c "cat /etc/letsencrypt/live/$i/fullchain.pem /etc/letsencrypt/live/$i/privkey.pem > $path/$i.pem" +done + +bash -c $command +# Reload HAProxy +sudo systemctl status haproxy \ No newline at end of file diff --git a/app/scripts/letsencrypt.sh b/app/scripts/letsencrypt.sh new file mode 100644 index 00000000..05c0a5f6 --- /dev/null +++ b/app/scripts/letsencrypt.sh @@ -0,0 +1,41 @@ +#!/bin/bash +for ARGUMENT in "$@" +do + KEY=$(echo $ARGUMENT | cut -f1 -d=) + VALUE=$(echo $ARGUMENT | cut -f2 -d=) + + case "$KEY" in + PROXY) PROXY=${VALUE} ;; + HOST) HOST=${VALUE} ;; + USER) USER=${VALUE} ;; + PASS) PASS=${VALUE} ;; + KEY) KEY=${VALUE} ;; + SSH_PORT) SSH_PORT=${VALUE} ;; + DOMAIN) DOMAIN=${VALUE} ;; + EMAIL) EMAIL=${VALUE} ;; + SSL_PATH) SSL_PATH=${VALUE} ;; + *) + esac +done + +export ANSIBLE_HOST_KEY_CHECKING=False +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False +export ACTION_WARNINGS=False +PWD=`pwd` +PWD=$PWD/scripts/ansible/ +echo $HOST > $PWD/$HOST + +if [[ $KEY == "" ]]; then + ansible-playbook $PWD/roles/letsencrypt.yml -e "ansible_user=$USER ansible_ssh_pass=$PASS ansible_port=$SSH_PORT variable_host=$HOST PROXY=$PROXY DOMAIN=$DOMAIN EMAIL=$EMAIL SSL_PATH=$SSL_PATH" -i $PWD/$HOST +else + ansible-playbook $PWD/roles/letsencrypt.yml --key-file $KEY -e "ansible_user=$USER ansible_port=$SSH_PORT variable_host=$HOST PROXY=$PROXY DOMAIN=$DOMAIN EMAIL=$EMAIL SSL_PATH=$SSL_PATH" -i $PWD/$HOST +fi + +if [ $? -gt 0 ] +then + echo "error: Can't create SSL certificate" + exit 1 +else + echo "ok" +fi +rm -f $PWD/$HOST diff --git a/app/sql.py b/app/sql.py index 7a4148e2..8c36f0b4 100644 --- a/app/sql.py +++ b/app/sql.py @@ -206,6 +206,7 @@ def add_setting_for_new_group(group_id): sql.append("INSERT INTO settings (param, value, section, `desc`, `group`) values('ldap_user_attribute', 'sAMAccountName', 'ldap', 'User attribute for search', " + group_id + ");") sql.append("INSERT INTO settings (param, value, section, `desc`, `group`) values('ldap_search_field', 'mail', 'ldap', 'Field where user e-mail saved', " + group_id + ");") sql.append("INSERT INTO settings (param, value, section, `desc`, `group`) values('ldap_type', '0', 'ldap', 'If 0 then will be used LDAP, if 1 then will be used LDAPS ', " + group_id + ");") + sql.append("INSERT INTO settings (param, value, section, `desc`, `group`) values('haproxy_enterprise', '0', 'haproxy', 'Use this option if your HAProxy is enterprise. It change service name for rebooting/reloading', " + group_id + ");") for i in sql: try: @@ -2165,12 +2166,12 @@ def smon_list(user_group): return cur.fetchall() -def insert_alerts(user_group, message): +def insert_alerts(user_group, level, ip, port, message, service): con, cur = get_cur() if mysql_enable == '1': - sql = """ insert into alerts (user_group, message, date) values('%s', '%s', now()) """ % (user_group, message) + sql = """ insert into alerts (user_group, message, level, ip, port, service, date) values('%s', '%s', '%s', '%s', '%s', '%s', now()) """ % (user_group, message, level, ip, port, service) else: - sql = """ insert into alerts (user_group, message, date) values('%s', '%s', datetime('now', 'localtime')) """ % (user_group, message) + sql = """ insert into alerts (user_group, message, level, ip, port, service, date) values('%s', '%s', '%s', '%s', '%s', '%s', datetime('now', 'localtime')) """ % (user_group, message, level, ip, port, service) try: cur.execute(sql) con.commit() @@ -2184,9 +2185,9 @@ def insert_alerts(user_group, message): def select_alerts(user_group): con, cur = get_cur() if mysql_enable == '1': - sql = """ select message, `date` from alerts where user_group = '%s' and `date` <= (now()+ INTERVAL 10 second) """ % (user_group) + sql = """ select level, message, `date` from alerts where user_group = '%s' and `date` <= (now()+ INTERVAL 10 second) """ % (user_group) else: - sql = """ select message, `date` from alerts where user_group = '%s' and `date` >= datetime('now', '-20 second', 'localtime') and `date` <= datetime('now', 'localtime') ; """ % (user_group) + sql = """ select level, message, `date` from alerts where user_group = '%s' and `date` >= datetime('now', '-20 second', 'localtime') and `date` <= datetime('now', 'localtime') ; """ % (user_group) try: cur.execute(sql) except sqltool.Error as e: diff --git a/app/templates/add.html b/app/templates/add.html index fb71f85f..aa39f8a6 100644 --- a/app/templates/add.html +++ b/app/templates/add.html @@ -526,6 +526,7 @@ h3 {
+ -

SSL

View certificates @@ -546,7 +547,6 @@ h3 {
Upload SSL certificates @@ -574,6 +574,40 @@ h3 {
+ + + + + + + + + + + + + + +

Let's Encrypt

+ Server + + Domain name + + E-mail +
+ + + {{ input('lets_domain', placeholder="example.com") }} + + {{ input('lets_email') }} + + +
diff --git a/app/templates/ajax/stick_table.html b/app/templates/ajax/stick_table.html index 7401d1d5..0b3697d1 100644 --- a/app/templates/ajax/stick_table.html +++ b/app/templates/ajax/stick_table.html @@ -11,7 +11,7 @@ { "searchable": false, "orderable": false, - "targets": {{headers|length - 1 }} + "targets": -1 } ], "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] diff --git a/app/templates/ajax/stick_tables.html b/app/templates/ajax/stick_tables.html index 131c3d64..9bf5c879 100644 --- a/app/templates/ajax/stick_tables.html +++ b/app/templates/ajax/stick_tables.html @@ -12,7 +12,7 @@ { "searchable": false, "orderable": false, - "targets": {{headers|length - 1 }} + "targets": -1 } ], "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] diff --git a/app/templates/runtimeapi.html b/app/templates/runtimeapi.html index 13fe5fb4..e8e4399c 100644 --- a/app/templates/runtimeapi.html +++ b/app/templates/runtimeapi.html @@ -12,6 +12,7 @@
  • Change IP and Port
  • Stick Table
  • Lists
  • +
  • Sessions
  • {% endif %} {% include 'include/login.html' %} @@ -35,6 +36,7 @@ {% if role <= 2 %} + {% endif %} @@ -217,8 +219,38 @@ You can read how it works here
    +
    + + + + + + + + + + +
    Server
    +
    + +
    + +
    +
    +
    + You can read how it works here +
    +
    {% endif %} +