Browse Source

* Breaking changes: Must remove subnet from client configurations in dashboard

* Added subnet support as described in #11
pull/26/head
Per-Arne 5 years ago
parent
commit
cf7d55d71a
  1. 2
      wg_dashboard_backend/main.py
  2. 21
      wg_dashboard_backend/migrations/versions/004_create_server_subnet.py
  3. 1
      wg_dashboard_backend/models.py
  4. 4
      wg_dashboard_backend/routers/v1/peer.py
  5. 1
      wg_dashboard_backend/schemas.py
  6. 2
      wg_dashboard_backend/templates/peer.j2
  7. 4
      wg_dashboard_backend/templates/server.j2
  8. 1
      wg_dashboard_frontend/src/app/interfaces/server.ts
  9. 15
      wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.html
  10. 18
      wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.ts
  11. 2
      wg_dashboard_frontend/src/app/page/dashboard/dashboard.module.ts
  12. 2
      wg_dashboard_frontend/src/app/page/dashboard/server/server.component.html
  13. 2
      wg_dashboard_frontend/src/app/validators/ip-address.validator.ts

2
wg_dashboard_backend/main.py

@ -37,7 +37,7 @@ _db: Session = SessionLocal()
if not database_exists(engine.url):
ADMIN_USERNAME = os.getenv("ADMIN_USERNAME")
if not ADMIN_USERNAME:
raise RuntimeError("Database does not exist and no ADMIN_USER is set")
raise RuntimeError("Database does not exist and no ADMIN_USERNAME is set")
ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD")

21
wg_dashboard_backend/migrations/versions/004_create_server_subnet.py

@ -0,0 +1,21 @@
from sqlalchemy import *
from migrate import *
def upgrade(migrate_engine):
try:
meta = MetaData(bind=migrate_engine)
server = Table('server', meta, autoload=True)
subnet = Column('subnet', Text)
subnet.create(server)
except:
pass
def downgrade(migrate_engine):
try:
meta = MetaData(bind=migrate_engine)
server = Table('server', meta, autoload=True)
server.c.subnet.drop()
except:
pass

1
wg_dashboard_backend/models.py

@ -21,6 +21,7 @@ class WGServer(Base):
id = Column(Integer, primary_key=True, index=True)
interface = Column(sqlalchemy.String, unique=True, index=True)
subnet = Column(sqlalchemy.Integer, nullable=False)
address = Column(sqlalchemy.String, unique=True)
listen_port = Column(sqlalchemy.String, unique=True)
private_key = Column(sqlalchemy.String)

4
wg_dashboard_backend/routers/v1/peer.py

@ -21,7 +21,7 @@ def add_peer(
server = schemas.WGServer(interface=peer_add.server_interface).from_db(sess)
peer = schemas.WGPeer(server_id=server.id)
address_space = set(ipaddress.ip_network(server.address, strict=False).hosts())
address_space = set(ipaddress.ip_network(f"{server.address}/{server.subnet}", strict=False).hosts())
occupied_space = set()
# Try add server IP to list.
@ -41,7 +41,7 @@ def add_peer(
address_space -= occupied_space
# Select first available address
peer.address = str(list(sorted(address_space)).pop(0)) + "/32"
peer.address = str(list(sorted(address_space)).pop(0))
# Private public key generation
keys = script.wireguard.generate_keys()

1
wg_dashboard_backend/schemas.py

@ -144,6 +144,7 @@ class PSK(GenericModel):
class WGServer(GenericModel):
id: int = None
address: str = None
subnet: int = None
interface: str
listen_port: int = None
endpoint: str = None

2
wg_dashboard_backend/templates/peer.j2

@ -1,5 +1,5 @@
[Interface]
Address = {{ data.peer.address.replace("/32", "/24") }}
Address = {{ data.peer.address }}/{{ data.server.subnet }}
PrivateKey = {{ data.peer.private_key }}
DNS = {{ data.peer.dns }}

4
wg_dashboard_backend/templates/server.j2

@ -1,5 +1,5 @@
[Interface]
Address = {{ data.address }}
Address = {{ data.address }}/{{ data.subnet }}
ListenPort = {{ data.listen_port }}
PrivateKey = {{ data.private_key }}
@ -13,5 +13,5 @@ PublicKey = {{ peer.public_key }}
{%- if peer.shared_key %}
PresharedKey = {{ peer.shared_key }}
{%- endif %}
AllowedIPs = {{ peer.address }}
AllowedIPs = {{ peer.address }}/32
{% endfor %}

1
wg_dashboard_frontend/src/app/interfaces/server.ts

@ -12,5 +12,6 @@ export interface Server {
post_up: string;
post_down: string;
configuration: string;
subnet: number;
peers: Peer[];
}

15
wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.html

@ -29,10 +29,21 @@
</td>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Address Scope</mat-label>
<input formControlName="address" matInput placeholder="10.0.200.1/24">
<mat-label>Address</mat-label>
<input formControlName="address" matInput placeholder="10.0.200.1">
</mat-form-field>
</td>
<td>
<mat-form-field matLine class="add-server-full-width">
<mat-label>Subnet</mat-label>
<select [(ngModel)]='selectedSubnet' matNativeControl formControlName="subnet">
<option *ngFor="let subnet of subnets" [value]="subnet">/{{subnet}}</option>
</select>
</mat-form-field>
</td>
</tr></table>
<table class="add-server-full-width" cellspacing="0"><tr>

18
wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.ts

@ -5,10 +5,10 @@ import { NumberValidator } from '../../../validators/number.validator';
import { Server } from '../../../interfaces/server';
import { ServerService } from '../../../services/server.service';
import { DataService } from '../../../services/data.service';
import Parser, {Property, Section, Sections} from "@jedmao/ini-parser";
import Parser, {Section} from "@jedmao/ini-parser";
import {Peer} from "../../../interfaces/peer";
import {forkJoin, from, Observable, of} from "rxjs";
import {concatAll, concatMap, filter, map, mergeAll, mergeMap, switchMap} from "rxjs/operators";
import {forkJoin, from} from "rxjs";
import {map, mergeMap} from "rxjs/operators";
import {NotifierService} from "angular-notifier";
@Component({
selector: 'app-add-server',
@ -34,13 +34,17 @@ export class AddServerComponent implements OnInit {
"DNS": "dns"
}
subnets = [];
selectedSubnet = 24;
serverForm: FormGroup = null;
isEdit = false;
editServer: Server = null;
initForm(){
this.serverForm = new FormGroup({
address: new FormControl('', [IPValidator.isIPAddress]),
address: new FormControl('', [Validators.required, IPValidator.isIPAddress]),
subnet: new FormControl('', [Validators.required, Validators.min(1), Validators.max(32)]),
interface: new FormControl('', [Validators.required, Validators.minLength(3)]),
listen_port: new FormControl('', [Validators.required, NumberValidator.stringIsNumber]),
endpoint: new FormControl('', Validators.required),
@ -62,6 +66,7 @@ export class AddServerComponent implements OnInit {
}
ngOnInit(): void {
this.subnets = Array(32).fill(1).map((x,i)=>i+1);
this.initForm();
this.comm.on('server-edit').subscribe((data: Server) => {
@ -140,11 +145,14 @@ export class AddServerComponent implements OnInit {
return false;
}
iFace.nodes["subnet"] = iFace.nodes["address"].split("/")[1];
iFace.nodes["address"] = iFace.nodes["address"].split("/")[0];
iFace.nodes["peers"] = sPeers
.map( x => x.nodes)
.map( x => {
x.server_id = -1;
x.address = x.allowed_ips; // Allowed_ips in server is the address of the peer (Seen from server perspective)
x.address = x.allowed_ips.split("/")[0]; // Allowed_ips in server is the address of the peer (Seen from server perspective)
x.allowed_ips = null; // This should be retrieved from peer data config
return x;
})

2
wg_dashboard_frontend/src/app/page/dashboard/dashboard.module.ts

@ -18,6 +18,7 @@ import { MatTableModule } from '@angular/material/table';
import { PeerComponent } from './peer/peer.component';
import { QRCodeModule } from 'angularx-qrcode';
import {MatTooltipModule} from "@angular/material/tooltip";
import {MatSelectModule} from "@angular/material/select";
@NgModule({
declarations: [
@ -43,6 +44,7 @@ import {MatTooltipModule} from "@angular/material/tooltip";
FormsModule,
QRCodeModule,
MatTooltipModule,
MatSelectModule,
],
})

2
wg_dashboard_frontend/src/app/page/dashboard/server/server.component.html

@ -83,7 +83,7 @@
</mat-card-title>
<mat-card-subtitle style="margin-top: 2px;">Endpoint: <b>{{server.endpoint}}:{{server.listen_port}}</b> - Address Space: <b>{{server.address}}</b></mat-card-subtitle>
<mat-card-subtitle style="margin-top: 2px;">Endpoint: <b>{{server.endpoint}}:{{server.listen_port}}</b> - Address: <b>{{server.address}}/{{server.subnet}}</b></mat-card-subtitle>
</mat-card-header>
<mat-card-content class="dashboard-card-content">

2
wg_dashboard_frontend/src/app/validators/ip-address.validator.ts

@ -4,7 +4,7 @@ import * as IPCIDR from 'ip-cidr';
export class IPValidator {
static isIPAddress(control: AbstractControl): ValidationErrors | null {
if (!control.value || !(new IPCIDR(control.value).isValid()) || !control.value.includes('/')) {
if (!control.value || !(new IPCIDR(control.value).isValid())) {
return { validIP: true };
}
return null;

Loading…
Cancel
Save