Latest handshake permanent

This commit is contained in:
Eduardo Silva 2024-02-23 18:18:52 -03:00
parent 8a89af4b55
commit 845fb82b22
8 changed files with 79 additions and 5 deletions

View File

@ -3,9 +3,11 @@ from django.views.decorators.http import require_http_methods
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
from wireguard.models import WebadminSettings from wireguard.models import WebadminSettings, Peer, PeerStatus
import requests import requests
import subprocess import subprocess
import datetime
import pytz
@login_required @login_required
@ -33,6 +35,8 @@ def wireguard_status(request):
if len(parts) >= 3: if len(parts) >= 3:
interface, peer, value = parts[0], parts[1], " ".join(parts[2:]) interface, peer, value = parts[0], parts[1], " ".join(parts[2:])
current_interface = interface current_interface = interface
elif len(parts) == 2 and current_interface:
peer, value = parts
else: else:
continue continue
@ -60,6 +64,43 @@ def wireguard_status(request):
return JsonResponse(output) return JsonResponse(output)
@require_http_methods(["GET"])
def cron_update_peer_latest_handshake(request):
command = "wg show all latest-handshakes | expand | tr -s ' '"
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
stdout, stderr = process.communicate()
if process.returncode != 0:
return JsonResponse({'error': stderr}, status=400)
#debug_information = []
for line in stdout.strip().split('\n'):
parts = line.split()
if len(parts) < 3:
continue
interface, peer_public_key, latest_handshake = parts[0], parts[1], parts[2]
latest_handshake_timestamp = int(latest_handshake)
if latest_handshake_timestamp > 0:
last_handshake_time = datetime.datetime.fromtimestamp(latest_handshake_timestamp, tz=pytz.utc)
#debug_information.append(f'Last handshake for {peer_public_key} is {last_handshake_time}')
peer = Peer.objects.filter(public_key=peer_public_key).first()
if peer:
#debug_information.append(f'Peer found: {peer.public_key}')
peer_status, created = PeerStatus.objects.get_or_create(
peer=peer,
defaults={'last_handshake': last_handshake_time}
)
if not created:
if peer_status.last_handshake != last_handshake_time:
#debug_information.append(f'Updating last_handshake for {peer.public_key} to {last_handshake_time}')
peer_status.last_handshake = last_handshake_time
peer_status.save()
#else:
# debug_information.append(f'No changes for {peer.public_key}')
return JsonResponse({'status': 'success'})
def cron_check_updates(request): def cron_check_updates(request):
webadmin_settings, webadmin_settings_created = WebadminSettings.objects.get_or_create(name='webadmin_settings') webadmin_settings, webadmin_settings_created = WebadminSettings.objects.get_or_create(name='webadmin_settings')

View File

@ -1 +1,2 @@
* * * * * root /usr/bin/curl -s http://wireguard-webadmin:8000/api/cron_check_updates/ >> /var/log/cron.log 2>&1 * * * * * root /usr/bin/curl -s http://wireguard-webadmin:8000/api/cron_check_updates/ >> /var/log/cron.log 2>&1
*/10 * * * * root /usr/bin/curl -s http://wireguard-webadmin:8000/api/cron_update_peer_latest_handshake/ >> /var/log/cron.log 2>&1

View File

@ -28,6 +28,7 @@ services:
command: /bin/bash /app/init.sh command: /bin/bash /app/init.sh
wireguard-webadmin-cron: wireguard-webadmin-cron:
container_name: wireguard-webadmin-cron
build: build:
context: ./cron context: ./cron
dockerfile: Dockerfile-cron dockerfile: Dockerfile-cron

View File

@ -27,6 +27,7 @@ services:
command: /bin/bash /app/init.sh command: /bin/bash /app/init.sh
wireguard-webadmin-cron: wireguard-webadmin-cron:
container_name: wireguard-webadmin-cron
build: build:
context: ./cron context: ./cron
dockerfile: Dockerfile-cron dockerfile: Dockerfile-cron

View File

@ -27,6 +27,7 @@ services:
command: /bin/bash /app/init.sh command: /bin/bash /app/init.sh
wireguard-webadmin-cron: wireguard-webadmin-cron:
container_name: wireguard-webadmin-cron
build: build:
context: ./cron context: ./cron
dockerfile: Dockerfile-cron dockerfile: Dockerfile-cron

View File

@ -36,7 +36,7 @@
{% comment %}This needs to be improved{% endcomment %} {% comment %}This needs to be improved{% endcomment %}
<p> <p>
<b>Transfer:</b> <span id="peer-transfer-{{ peer.public_key }}"></span><br> <b>Transfer:</b> <span id="peer-transfer-{{ peer.public_key }}"></span><br>
<b>Latest Handshake:</b> <span id="peer-latest-handshake-{{ peer.public_key }}"></span><br> <b>Latest Handshake:</b> <span id="peer-latest-handshake-{{ peer.public_key }}"></span> <span style="display: none;" id="peer-stored-latest-handshake-{{ peer.public_key }}">{% if peer.peerstatus.last_handshake %}{{ peer.peerstatus.last_handshake|date:"U" }}{% else %}0{% endif %}</span><br>
<b>Endpoints:</b> <span id="peer-endpoints-{{ peer.public_key }}"></span><br> <b>Endpoints:</b> <span id="peer-endpoints-{{ peer.public_key }}"></span><br>
<b>Allowed IPs: </b><span id="peer-allowed-ips-{{ peer.public_key }}"> <b>Allowed IPs: </b><span id="peer-allowed-ips-{{ peer.public_key }}">
{% for address in peer.peerallowedip_set.all %}{% if address.priority == 0 %} {% for address in peer.peerallowedip_set.all %}{% if address.priority == 0 %}
@ -125,10 +125,31 @@
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
//const fetchWireguardStatus = async () => {
// try {
// const response = await fetch('/api/wireguard_status/');
// const data = await response.json();
// updateUI(data);
// } catch (error) {
// console.error('Error fetching Wireguard status:', error);
// }
//};
const fetchWireguardStatus = async () => { const fetchWireguardStatus = async () => {
try { try {
const response = await fetch('/api/wireguard_status/'); const response = await fetch('/api/wireguard_status/');
const data = await response.json(); let data = await response.json();
// if latest-handshakes is 0, use the stored value
for (const [interfaceName, peers] of Object.entries(data)) {
for (const [peerId, peerInfo] of Object.entries(peers)) {
const peerElementId = `peer-stored-latest-handshake-${peerId}`;
const storedHandshakeElement = document.getElementById(peerElementId);
if (peerInfo['latest-handshakes'] === '0' && storedHandshakeElement) {
peerInfo['latest-handshakes'] = storedHandshakeElement.textContent;
}
}
}
updateUI(data); updateUI(data);
} catch (error) { } catch (error) {
console.error('Error fetching Wireguard status:', error); console.error('Error fetching Wireguard status:', error);

View File

@ -1,5 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import WireGuardInstance, Peer, PeerAllowedIP, WebadminSettings from .models import WireGuardInstance, Peer, PeerAllowedIP, PeerStatus, WebadminSettings
class WireGuardInstanceAdmin(admin.ModelAdmin): class WireGuardInstanceAdmin(admin.ModelAdmin):
@ -16,6 +16,13 @@ class PeerAdmin(admin.ModelAdmin):
admin.site.register(Peer, PeerAdmin) admin.site.register(Peer, PeerAdmin)
class PeerStatusAdmin(admin.ModelAdmin):
list_display = ('peer', 'last_handshake', 'created', 'updated', 'uuid')
search_fields = ('peer', 'last_handshake', 'created', 'updated', 'uuid')
admin.site.register(PeerStatus, PeerStatusAdmin)
class PeerAllowedIPAdmin(admin.ModelAdmin): class PeerAllowedIPAdmin(admin.ModelAdmin):
list_display = ('peer', 'priority', 'allowed_ip', 'netmask', 'created', 'updated', 'uuid') list_display = ('peer', 'priority', 'allowed_ip', 'netmask', 'created', 'updated', 'uuid')
search_fields = ('peer', 'priority', 'allowed_ip', 'netmask', 'created', 'updated', 'uuid') search_fields = ('peer', 'priority', 'allowed_ip', 'netmask', 'created', 'updated', 'uuid')

View File

@ -22,7 +22,7 @@ from console.views import view_console
from user_manager.views import view_user_list, view_manage_user from user_manager.views import view_user_list, view_manage_user
from accounts.views import view_create_first_user, view_login, view_logout from accounts.views import view_create_first_user, view_login, view_logout
from wireguard_tools.views import export_wireguard_configs, download_config_or_qrcode, restart_wireguard_interfaces from wireguard_tools.views import export_wireguard_configs, download_config_or_qrcode, restart_wireguard_interfaces
from api.views import wireguard_status, cron_check_updates from api.views import wireguard_status, cron_check_updates, cron_update_peer_latest_handshake
urlpatterns = [ urlpatterns = [
@ -44,5 +44,6 @@ urlpatterns = [
path('accounts/logout/', view_logout, name='logout'), path('accounts/logout/', view_logout, name='logout'),
path('api/wireguard_status/', wireguard_status, name='api_wireguard_status'), path('api/wireguard_status/', wireguard_status, name='api_wireguard_status'),
path('api/cron_check_updates/', cron_check_updates, name='cron_check_updates'), path('api/cron_check_updates/', cron_check_updates, name='cron_check_updates'),
path('api/cron_update_peer_latest_handshake/', cron_update_peer_latest_handshake, name='cron_update_peer_latest_handshake'),
] ]