# App Logwebmin

Aplikasi ini adalah hasil pengembangan mandiri Dinas Kominfo Bartim untuk memonitoring dan memblokir aktivitas client yang mencurigakan pada server webmin (server apache).

[![image.png](https://dokumen.baritotimurkab.go.id/uploads/images/gallery/2025-05/scaled-1680-/C5jx2dzf6eHZWzIq-image.png)](https://dokumen.baritotimurkab.go.id/uploads/images/gallery/2025-05/C5jx2dzf6eHZWzIq-image.png)

[![image.png](https://dokumen.baritotimurkab.go.id/uploads/images/gallery/2025-05/scaled-1680-/8i8cKmlIzcEyqXHL-image.png)](https://dokumen.baritotimurkab.go.id/uploads/images/gallery/2025-05/8i8cKmlIzcEyqXHL-image.png)

**Apikasi ini telah diinstall pada server Apache dengan spesifikasi:**

<div class="right-aligned" id="bkmrk--2"></div>1. <div class="right-aligned">CPU 8x Intel(R) Xeon(R) Bronze 3206R CPU @ 1.90GHz (1 Socket)</div>
2. RAM 32 GB
3. HDD 100GB
4. OS <span data-id="sysinfo_os">Linux Mint 20.2</span>

Aplikasi dapat diunduh pada link [**Cloud Repositori Bartim**.](https://drive.baritotimurkab.go.id/index.php/s/3FPMdLWejnB6HW5)

**Petunjuk Instalasi:**

1\. Upload file aplikasi pada /var/www/html/logwebmin

2\. Buat konfigurasi virtual domain pada /etc/apache2/sites-available/000-default.conf

<div id="bkmrk-%3Cvirtualhost-%2A%3A80%3E"><span style="color: rgb(224, 62, 45);">&lt;VirtualHost \*:80&gt;</span></div><div id="bkmrk-%C2%A0-%C2%A0-servername-log6."><span style="color: rgb(224, 62, 45);"> ServerName log6.baritotimurkab.go.id</span></div><div id="bkmrk-%C2%A0-%C2%A0-documentroot-%2Fva"><span style="color: rgb(224, 62, 45);"> DocumentRoot /var/www/html/logwebmin/public</span></div><div id="bkmrk--3"></div><div id="bkmrk-%C2%A0-%C2%A0-rewriteengine-on"><span style="color: rgb(224, 62, 45);"> RewriteEngine on</span></div><div id="bkmrk-%C2%A0-%C2%A0-documentroot-%2Fva-1"><span style="color: rgb(224, 62, 45);"> DocumentRoot /var/www/html/logwebmin/public</span></div><div id="bkmrk-%C2%A0-%C2%A0-rewritecond-%25%7Bse"><span style="color: rgb(224, 62, 45);"> RewriteCond %{SERVER\_NAME} =www.log6.baritotimurkab.go.id \[OR\]</span></div><div id="bkmrk-%C2%A0-%C2%A0-rewritecond-%25%7Bse-1"><span style="color: rgb(224, 62, 45);"> RewriteCond %{SERVER\_NAME} =log6.baritotimurkab.go.id</span></div><div id="bkmrk-%C2%A0-%C2%A0-rewriterule-%5E-ht"><span style="color: rgb(224, 62, 45);"> RewriteRule ^ https://%{SERVER\_NAME}%{REQUEST\_URI} \[END,NE,R=permanent\]</span></div><div id="bkmrk-%3C%2Fvirtualhost%3E"><span style="color: rgb(224, 62, 45);">&lt;/VirtualHost&gt;</span></div><div id="bkmrk--4">  
</div><div id="bkmrk--5"></div><div id="bkmrk--6"></div>3\. Buat ssl dengan letsencrypt

4\. Buat konfigurasi virtual domain ssl pada /etc/apache2/sites-available/default-ssl.conf

<div id="bkmrk-%3Cifmodule-mod_ssl.c%3E"><span style="color: rgb(224, 62, 45);">&lt;IfModule mod\_ssl.c&gt;</span></div><div id="bkmrk-%3Cvirtualhost-%2A%3A443%3E"><span style="color: rgb(224, 62, 45);">&lt;VirtualHost \*:443&gt;</span></div><div id="bkmrk-%C2%A0-%C2%A0-servername-log6.-1"><span style="color: rgb(224, 62, 45);"> ServerName log6.baritotimurkab.go.id</span></div><div id="bkmrk-%C2%A0-%C2%A0-documentroot-%2Fva-2"><span style="color: rgb(224, 62, 45);"> DocumentRoot /var/www/html/logwebmin/public</span></div><div id="bkmrk--7">  
</div><div id="bkmrk-%C2%A0-%C2%A0-sslengine-on"><span style="color: rgb(224, 62, 45);"> SSLEngine on</span></div><div id="bkmrk-%C2%A0-%C2%A0-sslcertificatefi"><span style="color: rgb(224, 62, 45);"> SSLCertificateFile /etc/letsencrypt/live/log6.baritotimurkab.go.id/fullchain.pem</span></div><div id="bkmrk-%C2%A0-%C2%A0-sslcertificateke"><span style="color: rgb(224, 62, 45);"> SSLCertificateKeyFile /etc/letsencrypt/live/log6.baritotimurkab.go.id/privkey.pem</span></div><div id="bkmrk-%C2%A0-%C2%A0-include-%2Fetc%2Flet"><span style="color: rgb(224, 62, 45);"> Include /etc/letsencrypt/options-ssl-apache.conf</span></div><div id="bkmrk-%C2%A0-%C2%A0-%C2%A0-%C2%A0%C2%A0"><span style="color: rgb(224, 62, 45);"> </span></div><div id="bkmrk-%C2%A0-%C2%A0-errorlog-%24%7Bapach"><span style="color: rgb(224, 62, 45);"> ErrorLog ${APACHE\_LOG\_DIR}/logwebmin\_error.log</span></div><div id="bkmrk-%C2%A0-%C2%A0-customlog-%24%7Bapac"><span style="color: rgb(224, 62, 45);"> CustomLog ${APACHE\_LOG\_DIR}/logwebmin\_access.log combined</span></div><div id="bkmrk-%3C%2Fvirtualhost%3E-1"><span style="color: rgb(224, 62, 45);">&lt;/VirtualHost&gt;</span></div><div id="bkmrk-%3C%2Fifmodule%3E"><span style="color: rgb(224, 62, 45);">&lt;/IfModule&gt;</span></div><div id="bkmrk--8"></div><div id="bkmrk--9"></div><div id="bkmrk--10"></div><div id="bkmrk--11"></div><div id="bkmrk--12"></div><div id="bkmrk--13"></div><div id="bkmrk--14"></div><div id="bkmrk-5.-buat-inisiasi-fit">  
5. Buat inisiasi fitur socket</div><div id="bkmrk--15"></div><div id="bkmrk-nano-%2Fetc%2Fsystemd%2Fsy">**nano /etc/systemd/system/ipblock.service**</div><div id="bkmrk-isi%3A">isi:</div><span style="color: rgb(224, 62, 45);">\[Unit\]</span>  
<span style="color: rgb(224, 62, 45);">Description=IP Blocking Service</span>  
<span style="color: rgb(224, 62, 45);">Requires=ipblock.socket</span>

<span style="color: rgb(224, 62, 45);">\[Service\]</span>  
<span style="color: rgb(224, 62, 45);">Type=simple</span>  
<span style="color: rgb(224, 62, 45);">ExecStart=/usr/local/bin/ipblock-daemon</span>  
<span style="color: rgb(224, 62, 45);">User=www-data</span>  
<span style="color: rgb(224, 62, 45);">Group=www-data</span>  
<span style="color: rgb(224, 62, 45);">Restart=always</span>  
<span style="color: rgb(224, 62, 45);">RestartSec=5</span>  
<span style="color: rgb(224, 62, 45);">Environment="SOCKET\_PATH=/var/www/html/logwebmin/storage/sockets/ipblock.sock"</span>

<span style="color: rgb(224, 62, 45);">\[Install\]</span>  
<span style="color: rgb(224, 62, 45);">WantedBy=multi-user.target</span>

**nano /etc/systemd/system/ipblock.socket**  
isi:  
<span style="color: rgb(224, 62, 45);">\[Unit\]</span>

<span style="color: rgb(224, 62, 45);">Description=IP Blocking Socket</span>

<span style="color: rgb(224, 62, 45);">\[Socket\]</span>  
<span style="color: rgb(224, 62, 45);">ListenStream=/var/www/html/logwebmin/storage/sockets/ipblock.sock</span>  
<span style="color: rgb(224, 62, 45);">SocketUser=www-data</span>  
<span style="color: rgb(224, 62, 45);">SocketGroup=www-data</span>  
<span style="color: rgb(224, 62, 45);">SocketMode=0660</span>

<span style="color: rgb(224, 62, 45);">\[Install\]</span>  
<span style="color: rgb(224, 62, 45);">WantedBy=sockets.target</span>

**nano /usr/local/bin/ipblock-daemon** (berikan permissions 0755 dan ownership www-data)  
isi:  
<span style="color: rgb(224, 62, 45);">\#!/usr/bin/python3</span>

<span style="color: rgb(224, 62, 45);">import socket</span>  
<span style="color: rgb(224, 62, 45);">import os</span>  
<span style="color: rgb(224, 62, 45);">import subprocess</span>  
<span style="color: rgb(224, 62, 45);">import re</span>

<span style="color: rgb(224, 62, 45);">SOCKET\_PATH = '/var/www/html/logwebmin/storage/sockets/ipblock.sock'</span>

<span style="color: rgb(224, 62, 45);">\# Setup socket directory</span>  
<span style="color: rgb(224, 62, 45);">os.makedirs(os.path.dirname(SOCKET\_PATH), exist\_ok=True)</span>

<span style="color: rgb(224, 62, 45);">\# Remove old socket if exists</span>  
<span style="color: rgb(224, 62, 45);">try:</span>  
<span style="color: rgb(224, 62, 45);"> os.unlink(SOCKET\_PATH)</span>  
<span style="color: rgb(224, 62, 45);">except FileNotFoundError:</span>  
<span style="color: rgb(224, 62, 45);"> pass</span>

<span style="color: rgb(224, 62, 45);">\# Create and bind socket</span>  
<span style="color: rgb(224, 62, 45);">sock = socket.socket(socket.AF\_UNIX, socket.SOCK\_STREAM)</span>  
<span style="color: rgb(224, 62, 45);">sock.bind(SOCKET\_PATH)</span>  
<span style="color: rgb(224, 62, 45);">sock.listen(1)</span>  
<span style="color: rgb(224, 62, 45);">os.chmod(SOCKET\_PATH, 0o660)</span>  
<span style="color: rgb(224, 62, 45);">os.chown(SOCKET\_PATH, 33, 33) # www-data user and group ID</span>

<span style="color: rgb(224, 62, 45);">def validate\_ip(ip):</span>  
<span style="color: rgb(224, 62, 45);"> """Validate IPv4 address format"""</span>  
<span style="color: rgb(224, 62, 45);"> pattern = r'^(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\]?)$'</span>  
<span style="color: rgb(224, 62, 45);"> return re.match(pattern, ip) is not None</span>

<span style="color: rgb(224, 62, 45);">while True:</span>  
<span style="color: rgb(224, 62, 45);"> conn, \_ = sock.accept()</span>  
<span style="color: rgb(224, 62, 45);"> try:</span>  
<span style="color: rgb(224, 62, 45);"> data = conn.recv(1024).decode().strip()</span>  
<span style="color: rgb(224, 62, 45);"> if not data:</span>  
<span style="color: rgb(224, 62, 45);"> continue</span>  
<span style="color: rgb(224, 62, 45);"> </span>  
<span style="color: rgb(224, 62, 45);"> # Handle unblock command</span>  
<span style="color: rgb(224, 62, 45);"> if data.startswith('unblock:'):</span>  
<span style="color: rgb(224, 62, 45);"> ip = data.split(':')\[1\]</span>  
<span style="color: rgb(224, 62, 45);"> if validate\_ip(ip):</span>  
<span style="color: rgb(224, 62, 45);"> try:</span>  
<span style="color: rgb(224, 62, 45);"> subprocess.run(\['sudo', '/usr/local/bin/unblock-ip.sh', ip\], check=True)</span>  
<span style="color: rgb(224, 62, 45);"> conn.send(b"OK")</span>  
<span style="color: rgb(224, 62, 45);"> except subprocess.CalledProcessError as e:</span>  
<span style="color: rgb(224, 62, 45);"> conn.send(f"ERROR: Unblock failed - {str(e)}".encode())</span>  
<span style="color: rgb(224, 62, 45);"> else:</span>  
<span style="color: rgb(224, 62, 45);"> conn.send(b"ERROR: Invalid IP format for unblock")</span>  
<span style="color: rgb(224, 62, 45);"> </span>  
<span style="color: rgb(224, 62, 45);"> # Handle block command (original functionality)</span>  
<span style="color: rgb(224, 62, 45);"> else:</span>  
<span style="color: rgb(224, 62, 45);"> ip = data</span>  
<span style="color: rgb(224, 62, 45);"> if validate\_ip(ip):</span>  
<span style="color: rgb(224, 62, 45);"> try:</span>  
<span style="color: rgb(224, 62, 45);"> subprocess.run(\['sudo', '/usr/local/bin/block-ip.sh', ip\], check=True)</span>  
<span style="color: rgb(224, 62, 45);"> conn.send(b"OK")</span>  
<span style="color: rgb(224, 62, 45);"> except subprocess.CalledProcessError as e:</span>  
<span style="color: rgb(224, 62, 45);"> conn.send(f"ERROR: Block failed - {str(e)}".encode())</span>  
<span style="color: rgb(224, 62, 45);"> else:</span>  
<span style="color: rgb(224, 62, 45);"> conn.send(b"ERROR: Invalid IP format for block")</span>  
<span style="color: rgb(224, 62, 45);"> </span>  
<span style="color: rgb(224, 62, 45);"> except Exception as e:</span>  
<span style="color: rgb(224, 62, 45);"> conn.send(f"ERROR: Server error - {str(e)}".encode())</span>  
<span style="color: rgb(224, 62, 45);"> finally:</span>  
<span style="color: rgb(224, 62, 45);"> conn.close()</span>

**nano /usr/local/bin/block-ip.sh**  
isi:  
<span style="color: rgb(224, 62, 45);">\#!/bin/bash</span>  
<span style="color: rgb(224, 62, 45);">IP=$1</span>  
<span style="color: rgb(224, 62, 45);">iptables -A INPUT -s $IP -j DROP</span>

**nano /usr/local/bin/unblock-ip.sh**  
isi:  
<span style="color: rgb(224, 62, 45);">\#!/bin/bash</span>  
<span style="color: rgb(224, 62, 45);">IP=$1</span>  
<span style="color: rgb(224, 62, 45);">iptables -D INPUT -s $IP -j DROP</span>

6\. Berikan akses www-data untuk menjalankan shell block-ip.sh dan unblock-ip.sh  
**nano /etc/sudoers**  
isi:  
<span style="color: rgb(224, 62, 45);">\#</span>

<span style="color: rgb(224, 62, 45);">\# This file MUST be edited with the 'visudo' command as root.</span>  
<span style="color: rgb(224, 62, 45);">\#</span>  
<span style="color: rgb(224, 62, 45);">\# Please consider adding local content in /etc/sudoers.d/ instead of</span>  
<span style="color: rgb(224, 62, 45);">\# directly modifying this file.</span>  
<span style="color: rgb(224, 62, 45);">\#</span>  
<span style="color: rgb(224, 62, 45);">\# See the man page for details on how to write a sudoers file.</span>  
<span style="color: rgb(224, 62, 45);">\#</span>  
<span style="color: rgb(224, 62, 45);">Defaults env\_reset</span>  
<span style="color: rgb(224, 62, 45);">Defaults mail\_badpass</span>  
<span style="color: rgb(224, 62, 45);">Defaults secure\_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"</span>

<span style="color: rgb(224, 62, 45);">\# Host alias specification</span>

<span style="color: rgb(224, 62, 45);">\# User alias specification</span>

<span style="color: rgb(224, 62, 45);">\# Cmnd alias specification</span>

<span style="color: rgb(224, 62, 45);">\# User privilege specification</span>  
<span style="color: rgb(224, 62, 45);">root ALL=(ALL:ALL) ALL</span>

<span style="color: rgb(224, 62, 45);">\# Members of the admin group may gain root privileges</span>  
<span style="color: rgb(224, 62, 45);">%admin ALL=(ALL) ALL</span>

<span style="color: rgb(224, 62, 45);">\# Allow members of group sudo to execute any command</span>  
<span style="color: rgb(224, 62, 45);">%sudo ALL=(ALL:ALL) ALL</span>

<span style="color: rgb(224, 62, 45);">\# See sudoers(5) for more information on "#include" directives:</span>

<span style="color: rgb(224, 62, 45);">\#includedir /etc/sudoers.d</span>

<span style="color: rgb(224, 62, 45);">**\#fungsi tambahan blokir lewa app logwebmin**</span>  
<span style="color: rgb(224, 62, 45);">www-data ALL=(ALL) NOPASSWD: /usr/local/bin/block-ip.sh</span>  
<span style="color: rgb(224, 62, 45);">www-data ALL=(ALL) NOPASSWD: /usr/local/bin/unblock-ip.sh</span>

7\. Jalankan service daemon  
**sudo systemctl daemon-reload**  
**sudo systemctl restart ipblock.socket ipblock.service**  
**sudo systemctl enable ipblock.socket**

8\. Verifikasi service  
**sudo systemctl status ipblock.service**  
**journalctl -u ipblock.service -f**

9\. Pastikan anda telah mendaftar akun pada [https://www.maxmind.com/](https://www.maxmind.com/)  
untuk mendapatkan license-key seperti pada contoh berikut:

[![image.png](https://dokumen.baritotimurkab.go.id/uploads/images/gallery/2025-05/scaled-1680-/O0KaS8oNtVVvEDcA-image.png)](https://dokumen.baritotimurkab.go.id/uploads/images/gallery/2025-05/O0KaS8oNtVVvEDcA-image.png)

agar dapat diinisiasikan pada .env

[![image.png](https://dokumen.baritotimurkab.go.id/uploads/images/gallery/2025-05/scaled-1680-/y4jcCgQRkdV15syq-image.png)](https://dokumen.baritotimurkab.go.id/uploads/images/gallery/2025-05/y4jcCgQRkdV15syq-image.png)