Browse Source
			
			
			
			
				
		# Conflicts: # wg_dashboard_backend/main.py # wg_dashboard_backend/migrations/versions/006_create_v6_subnet.pypull/109/head
				 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 * as IPCIDR from 'ip-cidr'; | |||
| import {Address4, Address6} from 'ip-address' | |||
| 
 | |||
| export class IPValidator { | |||
| 
 | |||
|   static isIPAddress(control: AbstractControl): ValidationErrors | null { | |||
|     if (!control.value  || !(new IPCIDR(control.value).isValid())) { | |||
|       return { validIP: true }; | |||
|     } | |||
|     return null; | |||
| 
 | |||
|     try { | |||
|       new Address4(control.value) | |||
|       return null | |||
|     } catch (e) {} | |||
|     try{ | |||
|       new Address6(control.value) | |||
|       return null | |||
|     } catch (e) {} | |||
|     return { validIP: true }; | |||
|   } | |||
| 
 | |||
| 
 | |||
| 
 | |||
| } | |||
|  | |||
					Loading…
					
					
				
		Reference in new issue