Browse Source
# Conflicts: # wg_dashboard_backend/main.py # wg_dashboard_backend/migrations/versions/006_create_v6_subnet.pypull/109/head
Per-Arne Andersen
4 years ago
20 changed files with 15750 additions and 13680 deletions
@ -0,0 +1,32 @@ |
|||||
|
--- |
||||
|
name: Bug report |
||||
|
about: Create a report to help us improve |
||||
|
title: '' |
||||
|
labels: bug |
||||
|
assignees: '' |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**Describe the bug** |
||||
|
A clear and concise description of what the bug is. |
||||
|
|
||||
|
**To Reproduce** |
||||
|
Steps to reproduce the behavior: |
||||
|
1. Go to '...' |
||||
|
2. Click on '....' |
||||
|
3. Scroll down to '....' |
||||
|
4. See error |
||||
|
|
||||
|
**Platform:** |
||||
|
- OS: RPI/Ubuntu/Windows/Docker ...etc |
||||
|
- Browser [e.g. chrome, safari] |
||||
|
- Version git-commit (If you updated and got error please try to record from -> to version |
||||
|
|
||||
|
**Stacktrace/error output** |
||||
|
Add any other context about the problem here. |
||||
|
|
||||
|
**Additional context** |
||||
|
Add any other context about the problem here. |
||||
|
|
||||
|
**Screenshots** |
||||
|
If applicable, add screenshots to help explain your problem. |
@ -0,0 +1,20 @@ |
|||||
|
--- |
||||
|
name: Feature request |
||||
|
about: Suggest an idea for this project |
||||
|
title: '' |
||||
|
labels: '' |
||||
|
assignees: '' |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**Is your feature request related to a problem? Please describe.** |
||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] |
||||
|
|
||||
|
**Describe the solution you'd like** |
||||
|
A clear and concise description of what you want to happen. |
||||
|
|
||||
|
**Describe alternatives you've considered** |
||||
|
A clear and concise description of any alternative solutions or features you've considered. |
||||
|
|
||||
|
**Additional context** |
||||
|
Add any other context or screenshots about the feature request here. |
@ -0,0 +1,25 @@ |
|||||
|
name: build wg-dashboard |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- master |
||||
|
|
||||
|
jobs: |
||||
|
build: |
||||
|
runs-on: ubuntu-latest |
||||
|
steps: |
||||
|
- name: checkout code |
||||
|
uses: actions/checkout@v2 |
||||
|
- name: install buildx |
||||
|
id: buildx |
||||
|
uses: crazy-max/ghaction-docker-buildx@v1 |
||||
|
with: |
||||
|
version: latest |
||||
|
- name: login to docker hub |
||||
|
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin |
||||
|
- name: build the image |
||||
|
run: | |
||||
|
docker buildx build --push \ |
||||
|
--tag perara/wg-manager:latest \ |
||||
|
--platform linux/amd64 . |
@ -0,0 +1,59 @@ |
|||||
|
# Build Docker Image from Github Repo |
||||
|
The steps below will walk you through installing the application in a docker container from the latest github version. |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
First thing we need to do is clone the github repository |
||||
|
```bash |
||||
|
git clone https://github.com/perara/wg-manager.git |
||||
|
``` |
||||
|
|
||||
|
Next we need to build the image. This will take some time. |
||||
|
```bash |
||||
|
docker build -t wg-manager . |
||||
|
``` |
||||
|
|
||||
|
Now that our image is built, we can either launch the container via _docker-compose_ or through the _docker CLI_. |
||||
|
|
||||
|
## Docker Compose |
||||
|
```yaml |
||||
|
version: "2.1" |
||||
|
services: |
||||
|
wireguard: |
||||
|
container_name: wg-manager |
||||
|
image: wg-manager |
||||
|
restart: always |
||||
|
sysctls: |
||||
|
net.ipv6.conf.all.disable_ipv6: 0 # Required for IPV6 |
||||
|
cap_add: |
||||
|
- NET_ADMIN |
||||
|
network_mode: host |
||||
|
ports: |
||||
|
- 51802:51802/udp |
||||
|
- 8888:8888 |
||||
|
volumes: |
||||
|
- ./wg-manager:/config |
||||
|
environment: |
||||
|
HOST: 0.0.0.0 |
||||
|
PORT: 8888 |
||||
|
ADMIN_USERNAME: admin |
||||
|
ADMIN_PASSWORD: admin |
||||
|
WEB_CONCURRENCY: 1 |
||||
|
``` |
||||
|
|
||||
|
## Docker CLI |
||||
|
```bash |
||||
|
docker run -d \ |
||||
|
--sysctl net.ipv6.conf.all.disable_ipv6=0 \ |
||||
|
--cap-add NET_ADMIN \ |
||||
|
--name wg-manager \ |
||||
|
--net host \ |
||||
|
-p "51802:51802/udp" \ |
||||
|
-p "8888:8888" \ |
||||
|
-v wg-manager:/config \ |
||||
|
-e HOST="0.0.0.0" \ |
||||
|
-e PORT="8888" \ |
||||
|
-e ADMIN_USERNAME="admin" \ |
||||
|
-e ADMIN_PASSWORD="admin" \ |
||||
|
wg-manager |
||||
|
``` |
@ -0,0 +1,173 @@ |
|||||
|
import os |
||||
|
from threading import Thread |
||||
|
|
||||
|
from script.obfuscate import BaseObfuscation, NotInstalledError |
||||
|
import re |
||||
|
import pathlib |
||||
|
import shutil |
||||
|
|
||||
|
current_dir = pathlib.Path(__file__).parent.absolute() |
||||
|
shapeshifter_path = current_dir.joinpath("binary/shapeshifter-dispatcher") |
||||
|
shapeshifter_binary = shapeshifter_path.joinpath("shapeshifter-dispatcher") |
||||
|
|
||||
|
|
||||
|
class GoNotFound(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
class GoVersionIncompatible(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
class GitNotInstalled(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
class ShapeShifterBase(BaseObfuscation): |
||||
|
MODES_SUPPORTED = ["server", "client"] |
||||
|
ALGORITHMS_SUPPORTED = ["obfs4"] |
||||
|
|
||||
|
def __init__(self, mode, algorithm, wireguard_port=None, listen_port=None, client_replicant_port=None, client_options=None): |
||||
|
super().__init__( |
||||
|
binary_path=shapeshifter_binary, |
||||
|
algorithm=algorithm |
||||
|
) |
||||
|
|
||||
|
assert mode in ShapeShifterBase.MODES_SUPPORTED, "%s is not a supported mode. Supported: %s" % ( |
||||
|
mode, ShapeShifterBase.MODES_SUPPORTED |
||||
|
) |
||||
|
|
||||
|
self._wireguard_port = wireguard_port |
||||
|
self._listen_port = listen_port |
||||
|
self._client_replicant_port = client_replicant_port |
||||
|
self._mode = mode |
||||
|
self._client_options = client_options |
||||
|
|
||||
|
self._go_version_min = (1, 14, 0) |
||||
|
|
||||
|
self.ensure_installed() |
||||
|
|
||||
|
def _verify_go_installed(self): |
||||
|
output, code = self.execute("version", override_command="go") |
||||
|
|
||||
|
try: |
||||
|
match = re.findall("go([0-9]+.[0-9]+.[0-9]+)", output) |
||||
|
match = match[0] |
||||
|
except IndexError: |
||||
|
raise GoNotFound("Go was not found on the system.") |
||||
|
|
||||
|
major, minor, patch = match.split(".") |
||||
|
|
||||
|
if int(major) < self._go_version_min[0] or int(minor) < self._go_version_min[1] or \ |
||||
|
int(patch) < self._go_version_min[2]: |
||||
|
raise GoVersionIncompatible("Go version is incompatible. %s < %s" % (self._go_version_min, match)) |
||||
|
|
||||
|
def _verify_git_installed(self): |
||||
|
output, code = self.execute("version", override_command="git") |
||||
|
if code == 0: |
||||
|
return |
||||
|
|
||||
|
raise GitNotInstalled("Git does not seem to be installed. Code: %s, Output: %s" % (code, output)) |
||||
|
|
||||
|
def _verify_shapeshifter_installed(self): |
||||
|
output, code = self.execute("version", override_command=shapeshifter_binary) |
||||
|
print(output, code) |
||||
|
|
||||
|
def _install_shapeshifter(self): |
||||
|
|
||||
|
if shapeshifter_path.is_dir(): |
||||
|
shutil.rmtree(shapeshifter_path) |
||||
|
|
||||
|
output, code = self.execute( |
||||
|
"clone", |
||||
|
"https://github.com/OperatorFoundation/shapeshifter-dispatcher.git", |
||||
|
shapeshifter_path, |
||||
|
override_command="git") |
||||
|
|
||||
|
assert code == 0, "Git exited with error. %s" % (output,) |
||||
|
|
||||
|
current_working_dir = os.getcwd() |
||||
|
os.chdir(shapeshifter_path) |
||||
|
|
||||
|
output, code = self.execute("build", override_command="go") |
||||
|
os.chdir(current_working_dir) |
||||
|
|
||||
|
assert code == 0, "Building shapeshifter failed with output: %s" % (output,) |
||||
|
|
||||
|
def ensure_installed(self): |
||||
|
try: |
||||
|
super().ensure_installed() |
||||
|
except NotInstalledError: |
||||
|
|
||||
|
self._verify_go_installed() |
||||
|
self._verify_git_installed() |
||||
|
|
||||
|
try: |
||||
|
self._verify_shapeshifter_installed() |
||||
|
except FileNotFoundError: |
||||
|
self._install_shapeshifter() |
||||
|
|
||||
|
def start(self): |
||||
|
|
||||
|
bind_command = "bindaddr" if self._mode == "server" else "proxylistenaddr" |
||||
|
bind_port = self._listen_port if self._mode == "server" else self._client_replicant_port |
||||
|
bind_value = f"127.0.0.1:{bind_port}" # TODO |
||||
|
if self._mode == "server": |
||||
|
bind_value = self.algorithm + "-" + bind_value |
||||
|
connect_command = "orport" if self._mode == "server" else "target" |
||||
|
connect_port = self._wireguard_port if self._mode == "server" else self._listen_port |
||||
|
|
||||
|
cmd = [ |
||||
|
"-transparent", |
||||
|
"-udp", |
||||
|
f"-{self._mode}", |
||||
|
"-state", f"state", |
||||
|
f"-{connect_command}", f"127.0.0.1:{connect_port}", |
||||
|
"-transports", self.algorithm, |
||||
|
f"-{bind_command}", bind_value |
||||
|
] |
||||
|
|
||||
|
if self._mode == "client": |
||||
|
cmd.extend([ |
||||
|
"-options", f"{self._client_options}" |
||||
|
]) |
||||
|
|
||||
|
cmd.extend([ |
||||
|
"-logLevel", "DEBUG", |
||||
|
"-enableLogging", |
||||
|
]) |
||||
|
print(*cmd) |
||||
|
output, code = self.execute(*cmd, stream=True, prefix=self._mode) |
||||
|
print(output, code) |
||||
|
|
||||
|
def start_threaded(self): |
||||
|
t = Thread(target=self.start, args=()) |
||||
|
t.start() |
||||
|
return t |
||||
|
|
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
import time |
||||
|
x = ShapeShifterBase( |
||||
|
mode="server", |
||||
|
algorithm="obfs2", |
||||
|
wireguard_port=3333, |
||||
|
listen_port=2222, |
||||
|
) |
||||
|
x.start_threaded() |
||||
|
|
||||
|
time.sleep(1) |
||||
|
|
||||
|
x = ShapeShifterBase( |
||||
|
mode="client", |
||||
|
algorithm="obfs2", |
||||
|
listen_port=2222, |
||||
|
client_replicant_port=1443, |
||||
|
client_options='{"cert": "BWvGMVn3C8daXai2Xo+If23XS94eztZE9Kbtykvy9x5ADWc6YCHdGlWQfDh1fzu7AhuTIA", "iat-mode": "0"}' |
||||
|
) |
||||
|
x.start_threaded() |
||||
|
|
||||
|
|
||||
|
|
||||
|
while True: |
||||
|
time.sleep(1) |
File diff suppressed because it is too large
@ -1,12 +1,22 @@ |
|||||
import { AbstractControl, ValidationErrors } from '@angular/forms'; |
import { AbstractControl, ValidationErrors } from '@angular/forms'; |
||||
import * as IPCIDR from 'ip-cidr'; |
import * as IPCIDR from 'ip-cidr'; |
||||
|
import {Address4, Address6} from 'ip-address' |
||||
|
|
||||
export class IPValidator { |
export class IPValidator { |
||||
|
|
||||
static isIPAddress(control: AbstractControl): ValidationErrors | null { |
static isIPAddress(control: AbstractControl): ValidationErrors | null { |
||||
if (!control.value || !(new IPCIDR(control.value).isValid())) { |
|
||||
return { validIP: true }; |
try { |
||||
} |
new Address4(control.value) |
||||
return null; |
return null |
||||
|
} catch (e) {} |
||||
|
try{ |
||||
|
new Address6(control.value) |
||||
|
return null |
||||
|
} catch (e) {} |
||||
|
return { validIP: true }; |
||||
} |
} |
||||
|
|
||||
|
|
||||
|
|
||||
} |
} |
||||
|
Loading…
Reference in new issue