├── .circleci └── config.yml ├── .github ├── CHANNELS.md ├── CODEOWNERS ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ ├── feature_request.md │ └── pull_request_template.md ├── STATUS.md ├── dependabot.yml ├── docs │ └── _config.yml └── workflows │ ├── auto-update-blocked-hosts.yaml │ ├── auto-update-named-cache.yml │ ├── build-latest-version.yml │ ├── deploy-github-pages.yml │ ├── monthly-application-release.yml │ └── shell-check-wireguard-manager.yml ├── assets ├── Wireguard-Manager.png ├── ad-blocker-vs-no-ad-blocker.mp4 ├── hosts ├── images │ └── icons │ │ ├── aws.svg │ │ ├── digitalocean.svg │ │ ├── discord.svg │ │ ├── gcp.svg │ │ ├── linode.svg │ │ └── slack.svg ├── named.cache └── readme.md ├── code_of_conduct.md ├── license.md ├── readme.md ├── security.md └── wireguard-manager.sh /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | # Define the commands to be used in the jobs 4 | commands: 5 | # Define a command to install necessary dependencies 6 | install_dependencies: 7 | description: "Install necessary dependencies" 8 | parameters: 9 | update_command: 10 | type: string 11 | install_command: 12 | type: string 13 | packages: 14 | type: string 15 | steps: 16 | - run: | 17 | << parameters.update_command >> 18 | << parameters.install_command >> << parameters.packages >> 19 | 20 | # Define a command to configure the environment and execute WireGuard Manager 21 | configure_and_execute: 22 | description: "Configure environment and execute WireGuard Manager" 23 | steps: 24 | - run: 25 | name: Configure environment and execute WireGuard Manager 26 | command: | 27 | curl https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/wireguard-manager.sh --create-dirs -o /usr/local/bin/wireguard-manager.sh 28 | chmod +x /usr/local/bin/wireguard-manager.sh 29 | bash /usr/local/bin/wireguard-manager.sh --install 30 | 31 | # Define the jobs to be used in the workflows 32 | jobs: 33 | test_on_alma: 34 | description: "Test on AlmaLinux" 35 | docker: 36 | - image: almalinux:latest 37 | steps: 38 | - checkout 39 | - install_dependencies: 40 | update_command: dnf -y update 41 | install_command: dnf -y install --allowerasing 42 | packages: curl bash coreutils 43 | - configure_and_execute 44 | 45 | # Define a job to test on Alpine Linux 46 | test_on_alpine: 47 | description: "Test on Alpine Linux" 48 | docker: 49 | - image: alpine:latest 50 | steps: 51 | - checkout 52 | - install_dependencies: 53 | update_command: apk update 54 | install_command: apk add 55 | packages: curl bash coreutils 56 | - configure_and_execute 57 | 58 | # Define a job to test on Arch Linux 59 | test_on_arch: 60 | description: "Test on Arch Linux" 61 | docker: 62 | - image: archlinux:latest 63 | steps: 64 | - checkout 65 | - install_dependencies: 66 | update_command: pacman -Syu --noconfirm 67 | install_command: pacman -S --noconfirm 68 | packages: curl bash coreutils 69 | - configure_and_execute 70 | 71 | test_on_centos: 72 | description: "Test on CentOS" 73 | docker: 74 | - image: centos:latest 75 | steps: 76 | - checkout 77 | - install_dependencies: 78 | update_command: dnf -y update 79 | install_command: dnf -y install --allowerasing 80 | packages: curl bash coreutils 81 | - configure_and_execute 82 | 83 | # Define a job to test on Debian 84 | test_on_debian: 85 | description: "Test on Debian" 86 | docker: 87 | - image: debian:latest 88 | steps: 89 | - checkout 90 | - install_dependencies: 91 | update_command: apt-get update 92 | install_command: apt-get -y install 93 | packages: curl bash coreutils 94 | - configure_and_execute 95 | 96 | # Define a job to test on Fedora 97 | test_on_fedora: 98 | description: "Test on Fedora" 99 | docker: 100 | - image: fedora:latest 101 | steps: 102 | - checkout 103 | - install_dependencies: 104 | update_command: dnf -y update 105 | install_command: dnf -y install --allowerasing 106 | packages: curl bash coreutils 107 | - configure_and_execute 108 | 109 | # Define a job to test on Kali Linux 110 | test_on_kali: 111 | description: "Test on Kali Linux" 112 | docker: 113 | - image: kalilinux/kali-rolling 114 | steps: 115 | - checkout 116 | - install_dependencies: 117 | update_command: apt-get update 118 | install_command: apt-get -y install 119 | packages: curl bash coreutils 120 | - configure_and_execute 121 | 122 | # Define a job to test on Linux Mint 123 | test_on_mint: 124 | description: "Test on Linux Mint" 125 | docker: 126 | - image: linuxmintd/mint20.3-amd64 127 | steps: 128 | - checkout 129 | - install_dependencies: 130 | update_command: apt-get update 131 | install_command: apt-get -y install 132 | packages: curl bash coreutils 133 | - configure_and_execute 134 | 135 | # Define a job to test on Manjaro Linux 136 | test_on_manjaro: 137 | description: "Test on Manjaro Linux" 138 | docker: 139 | - image: manjarolinux/base 140 | steps: 141 | - checkout 142 | - install_dependencies: 143 | update_command: pacman -Syu --noconfirm 144 | install_command: pacman -S --noconfirm 145 | packages: curl bash coreutils 146 | - configure_and_execute 147 | 148 | # Define a job to test on KDE Neon 149 | test_on_neon: 150 | description: "Test on KDE Neon" 151 | docker: 152 | - image: kdeneon/plasma:user 153 | steps: 154 | - checkout 155 | - install_dependencies: 156 | update_command: apt-get update 157 | install_command: apt-get -y install 158 | packages: curl bash coreutils 159 | - configure_and_execute 160 | 161 | # Define a job to test on Oracle Linux 162 | test_on_oracle: 163 | description: "Test on Oracle Linux" 164 | docker: 165 | - image: oraclelinux:8 166 | steps: 167 | - checkout 168 | - install_dependencies: 169 | update_command: dnf -y update 170 | install_command: dnf -y install 171 | packages: curl bash coreutils 172 | - configure_and_execute 173 | 174 | # Define a job to test on Red Hat Enterprise Linux 175 | test_on_rhel: 176 | description: "Test on Red Hat Enterprise Linux" 177 | docker: 178 | - image: registry.access.redhat.com/ubi8/ubi 179 | steps: 180 | - checkout 181 | - install_dependencies: 182 | update_command: dnf -y update 183 | install_command: dnf -y install --allowerasing 184 | packages: curl bash coreutils 185 | - configure_and_execute 186 | 187 | # Define a job to test on Rocky Linux 188 | test_on_rocky: 189 | description: "Test on Rocky Linux" 190 | docker: 191 | - image: rockylinux/rockylinux 192 | steps: 193 | - checkout 194 | - install_dependencies: 195 | update_command: dnf -y update 196 | install_command: dnf -y install --allowerasing 197 | packages: curl bash coreutils 198 | - configure_and_execute 199 | 200 | # Define a job to test on Ubuntu 201 | test_on_ubuntu: 202 | description: "Test on Ubuntu" 203 | docker: 204 | - image: ubuntu:latest 205 | steps: 206 | - checkout 207 | - install_dependencies: 208 | update_command: apt-get update 209 | install_command: apt-get -y install 210 | packages: curl bash coreutils 211 | - configure_and_execute 212 | 213 | # Define the workflows 214 | workflows: 215 | version: 2 216 | comprehensive_tests: 217 | description: "Perform comprehensive tests on multiple Linux distributions" 218 | jobs: 219 | - test_on_alma 220 | - test_on_alpine 221 | - test_on_arch 222 | - test_on_centos 223 | - test_on_debian 224 | - test_on_fedora 225 | - test_on_kali 226 | - test_on_mint 227 | - test_on_manjaro 228 | - test_on_neon 229 | - test_on_oracle 230 | - test_on_rhel 231 | - test_on_rocky 232 | - test_on_ubuntu 233 | -------------------------------------------------------------------------------- /.github/CHANNELS.md: -------------------------------------------------------------------------------- 1 | `master` 2 | 3 | The current tip-of-tree, absolute latest cutting edge build. Usually functional, though sometimes we accidentally break things. 4 | 5 | `dev` 6 | 7 | The latest fully-tested build. Usually functional, but see Bad Builds for a list of known "bad" dev builds. We continually try to roll master to dev. Doing so involves running many more tests than those that we run during master development, which is why this is not the same to master. 8 | 9 | `beta` 10 | 11 | Every month, we pick the "best" dev build of the previous month or so, and promote it to beta. These builds have been tested. 12 | 13 | `stable` 14 | 15 | When we believe we have a particularly useful build, we promote it to the stable channel. We intend to do this more or less every quarter, but this may vary. We recommend that you use this channel for all production app releases. We may ship hotfixes to the stable channel for high-priority bugs, although we intend to do this rarely. 16 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This is a comment. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # These owners will be the default owners for everything in 5 | # the repo. Unless a later match takes precedence, 6 | # @global-owner1 and @global-owner2 will be requested for 7 | # review when someone opens a pull request. 8 | 9 | # Order is important; the last matching pattern takes the most 10 | # precedence. When someone opens a pull request that only 11 | # modifies JS files, only @js-owner and not the global 12 | # owner(s) will be requested for a review. 13 | 14 | # You can also use email addresses if you prefer. They'll be 15 | # used to look up users just like we do for commit author 16 | # emails. 17 | 18 | # In this example, @doctocat owns any files in the build/logs 19 | # directory at the root of the repository and any of its 20 | # subdirectories. 21 | 22 | # The `docs/*` pattern will match files like 23 | # `docs/getting-started.md` but not further nested files like 24 | # `docs/build-app/troubleshooting.md`. 25 | 26 | # In this example, @octocat owns any file in an apps directory 27 | # anywhere in your repository. 28 | 29 | # In this example, @doctocat owns any file in the `/docs` 30 | # directory in the root of your repository. 31 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Thank you for contributing 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report to help us improve 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | 28 | - OS: [e.g. iOS] 29 | - Browser [e.g. chrome, safari] 30 | - Version [e.g. 22] 31 | 32 | **Smartphone (please complete the following information):** 33 | 34 | - Device: [e.g. iPhone6] 35 | - OS: [e.g. iOS8.1] 36 | - Browser [e.g. stock browser, safari] 37 | - Version [e.g. 22] 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/pull_request_template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: pull requests 3 | about: Pull requests let you tell others about changes you've pushed to a branch in a repository 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Describe the PR** 10 | 11 | A clear and concise description of what the pull request is. 12 | 13 | **Which issue(s) this PR fixes**: 14 | 15 | Fixes # 16 | 17 | **Special notes for your reviewer**: 18 | 19 | **Does this PR introduce a user-facing change?**: 20 | 21 | **Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.**: 22 | 23 | **Additional context** 24 | 25 | Add any other context about the pull request here. 26 | -------------------------------------------------------------------------------- /.github/STATUS.md: -------------------------------------------------------------------------------- 1 | `complete` :heavy_check_mark: 2 | 3 | Most of the project is completed, some bug fixing or security fixing may take place. 4 | 5 | `active` :heart: 6 | 7 | The venture is under active growth. 8 | 9 | `abandoned` :x: 10 | 11 | There could be an unfinished project, Identified as a project that for the purposes of this analysis has been entirely abandoned, or indefinitely postponed. At any point of a project lifecycle, abandonment can occur and cause severe losses. 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | -------------------------------------------------------------------------------- /.github/docs/_config.yml: -------------------------------------------------------------------------------- 1 | auto: true 2 | -------------------------------------------------------------------------------- /.github/workflows/auto-update-blocked-hosts.yaml: -------------------------------------------------------------------------------- 1 | # Name of the workflow 2 | name: Automated Update of Blocked Hosts File 3 | 4 | # Define the events that trigger the workflow 5 | on: 6 | # Trigger the workflow on a schedule (every day at midnight) 7 | schedule: 8 | - cron: "0 0 * * *" 9 | # Allow manual triggering of the workflow 10 | workflow_dispatch: 11 | 12 | # Define the jobs in the workflow 13 | jobs: 14 | # Define a job named "build" 15 | build: 16 | # Name of the job that will be displayed on GitHub 17 | name: Automated Hosts File Update 18 | # The type of runner that the job will run on 19 | runs-on: ubuntu-latest 20 | # Environment variables available to all steps in the job 21 | env: 22 | CONTENT_BLOCKER_URL: https://raw.githubusercontent.com/complexorganizations/content-blocker/main/assets/hosts 23 | CONTENT_BLOCKER_PATH: assets/hosts 24 | 25 | steps: 26 | # Check out the repository code 27 | - name: Check out code 28 | uses: actions/checkout@v4 # Updated to use the latest version for better compatibility and features 29 | 30 | # Get the current SHA-3-512 hash of the file 31 | - name: Get current hash 32 | run: | 33 | CONTENT_BLOCKER_CURRENT_HASH=$(openssl dgst -sha3-512 "${{ env.CONTENT_BLOCKER_PATH }}" | awk '{print $2}') 34 | echo "CONTENT_BLOCKER_CURRENT_HASH=$CONTENT_BLOCKER_CURRENT_HASH" >> $GITHUB_ENV 35 | 36 | # Get the future SHA-3-512 hash of the file 37 | - name: Get future hash 38 | run: | 39 | CONTENT_BLOCKER_FUTURE_HASH=$(curl --silent "${{ env.CONTENT_BLOCKER_URL }}" | openssl dgst -sha3-512 | awk '{print $2}') 40 | echo "CONTENT_BLOCKER_FUTURE_HASH=$CONTENT_BLOCKER_FUTURE_HASH" >> $GITHUB_ENV 41 | 42 | # Check if an update is needed 43 | - name: Check for update 44 | run: | 45 | if [ "$CONTENT_BLOCKER_CURRENT_HASH" != "$CONTENT_BLOCKER_FUTURE_HASH" ]; then 46 | curl -o "${{ env.CONTENT_BLOCKER_PATH }}" "${{ env.CONTENT_BLOCKER_URL }}" 47 | else 48 | echo "No update needed" 49 | exit 0 50 | fi 51 | 52 | # Push the updated file to GitHub 53 | - name: Push updated hosts file 54 | run: | 55 | git config user.name github-actions 56 | git config user.email github-actions@github.com 57 | if git diff --exit-code --quiet -- "${{ env.CONTENT_BLOCKER_PATH }}"; then 58 | echo "No changes to commit" 59 | exit 0 60 | else 61 | git add "${{ env.CONTENT_BLOCKER_PATH }}" 62 | git commit -m "Update hosts file $(date)" 63 | git push 64 | fi 65 | -------------------------------------------------------------------------------- /.github/workflows/auto-update-named-cache.yml: -------------------------------------------------------------------------------- 1 | # Name of the workflow 2 | name: Automated Update of Named Cache 3 | 4 | # Define the events that trigger the workflow 5 | on: 6 | # Trigger the workflow on a schedule (every day at midnight) 7 | schedule: 8 | - cron: "0 0 * * *" 9 | # Allow manual triggering of the workflow 10 | workflow_dispatch: 11 | 12 | # Define the jobs in the workflow 13 | jobs: 14 | # Define a job named "build" 15 | build: 16 | # Name of the job that will be displayed on GitHub 17 | name: Refresh Named Cache 18 | # The type of runner that the job will run on 19 | runs-on: ubuntu-latest 20 | # Environment variables available to all steps in the job 21 | env: 22 | NAMED_CACHE_URL: https://www.internic.net/domain/named.cache 23 | NAMED_CACHE_PATH: assets/named.cache 24 | 25 | steps: 26 | # Check out the repository code 27 | - name: Check out code 28 | uses: actions/checkout@v4 # Updated to use the latest version for better compatibility and features 29 | 30 | # Get the current SHA-3-512 hash of the file 31 | - name: Get current hash 32 | run: | 33 | echo "NAMED_CACHE_CURRENT_HASH=$(openssl dgst -sha3-512 "${{ env.NAMED_CACHE_PATH }}" | awk '{print $2}')" >> $GITHUB_ENV 34 | 35 | # Get the future SHA-3-512 hash of the file 36 | - name: Get future hash 37 | run: | 38 | echo "NAMED_CACHE_FUTURE_HASH=$(curl --silent "${{ env.NAMED_CACHE_URL }}" | openssl dgst -sha3-512 | awk '{print $2}')" >> $GITHUB_ENV 39 | 40 | # Check if an update is needed 41 | - name: Check for update 42 | run: | 43 | if [ "$NAMED_CACHE_CURRENT_HASH" != "$NAMED_CACHE_FUTURE_HASH" ]; then 44 | curl -o "${{ env.NAMED_CACHE_PATH }}" "${{ env.NAMED_CACHE_URL }}" 45 | else 46 | echo "No update needed" 47 | exit 0 48 | fi 49 | 50 | # Push the updated file to GitHub 51 | - name: Push updated named.cache 52 | run: | 53 | git config user.name github-actions 54 | git config user.email github-actions@github.com 55 | if git diff --exit-code --quiet -- "${{ env.NAMED_CACHE_PATH }}"; then 56 | echo "No changes to commit" 57 | exit 0 58 | else 59 | git add "${{ env.NAMED_CACHE_PATH }}" 60 | git commit -m "Update named.cache $(date)" 61 | git push 62 | fi 63 | -------------------------------------------------------------------------------- /.github/workflows/build-latest-version.yml: -------------------------------------------------------------------------------- 1 | # Name of the workflow 2 | name: Construct Most Recent Release 3 | 4 | # Define the events that trigger the workflow 5 | on: 6 | # Trigger the workflow on push events 7 | push: 8 | # Only for .sh files 9 | paths: 10 | - "**.sh" 11 | # Trigger the workflow on pull request events 12 | pull_request: 13 | # Only for .sh files 14 | paths: 15 | - "**.sh" 16 | # Allow manual triggering of the workflow 17 | workflow_dispatch: 18 | 19 | # Define the jobs in the workflow 20 | jobs: 21 | # Define a job named "build" 22 | build: 23 | # Name of the job that will be displayed on GitHub 24 | name: Build on Ubuntu 25 | # The type of runner that the job will run on 26 | runs-on: ubuntu-latest 27 | # Environment variables available to all steps in the job 28 | env: 29 | IP_SERVICE_NAME: checkip.amazonaws.com 30 | IP_SERVICE_URL: https://checkip.amazonaws.com 31 | # Define the steps in the job 32 | steps: 33 | # Check out the repository code 34 | - name: Check out Repository Code 35 | uses: actions/checkout@v4 36 | 37 | # Install required tools 38 | - name: Install Required Tools 39 | run: sudo apt-get update && sudo apt-get install curl -y 40 | 41 | # Test network connectivity 42 | - name: Test Network Connectivity 43 | run: curl "${{ env.IP_SERVICE_URL }}" 44 | 45 | # Install WireGuard Manager 46 | - name: Install WireGuard Manager 47 | run: sudo ./wireguard-manager.sh --install 48 | 49 | # Stop WireGuard service 50 | - name: Stop WireGuard Service 51 | run: sudo ./wireguard-manager.sh --stop 52 | 53 | # Start WireGuard service 54 | - name: Start WireGuard Service 55 | run: sudo ./wireguard-manager.sh --start 56 | 57 | # Restart WireGuard service 58 | - name: Restart WireGuard Service 59 | run: sudo ./wireguard-manager.sh --restart 60 | 61 | # View WireGuard status 62 | - name: View WireGuard Status 63 | run: sudo systemctl status wg-quick@wg0 64 | 65 | # Add multiple WireGuard peers 66 | - name: Add Multiple WireGuard Peers 67 | run: for i in {1..10}; do echo -e "\n" | sudo ./wireguard-manager.sh --add; done 68 | 69 | # Update dynamic DNS settings 70 | - name: Update Dynamic DNS Settings 71 | run: sudo ./wireguard-manager.sh --ddns 72 | 73 | # Create WireGuard backup 74 | - name: Create WireGuard Backup 75 | run: sudo ./wireguard-manager.sh --backup 76 | 77 | # List WireGuard peers 78 | - name: List WireGuard Peers 79 | run: sudo ./wireguard-manager.sh --list 80 | 81 | # Update WireGuard Manager 82 | - name: Update WireGuard Manager 83 | run: sudo ./wireguard-manager.sh --update 84 | 85 | # Change permissions to allow access 86 | - name: Allow acess to the files 87 | run: sudo chmod -R 777 /etc/wireguard/ 88 | 89 | # Display Configuration Files 90 | - name: Show Configuration Files 91 | run: | 92 | [ -f /etc/wireguard/wg0.conf ] && cat /etc/wireguard/wg0.conf || echo "wg0.conf not found" 93 | [ -f /etc/unbound/unbound.conf ] && cat /etc/unbound/unbound.conf || echo "unbound.conf not found" 94 | [ -f /var/lib/unbound/root.key ] && cat /var/lib/unbound/root.key || echo "root.key not found" 95 | [ -f /etc/unbound/root.hints ] && cat /etc/unbound/root.hints || echo "root.hints not found" 96 | [ -f /etc/unbound/unbound.conf.d/hosts.conf ] && cat /etc/unbound/unbound.conf.d/hosts.conf || echo "hosts.conf not found" 97 | [ -f /etc/resolv.conf ] && cat /etc/resolv.conf || echo "resolv.conf not found" 98 | for file in /etc/wireguard/clients/*; do 99 | if [ -f "$file" ]; then 100 | echo "Showing $file" 101 | cat "$file" 102 | else 103 | echo "File $file not found" 104 | fi 105 | done 106 | 107 | # Change permissions to deny access 108 | - name: Restore deny acess to the files 109 | run: sudo chmod -R 600 /etc/wireguard/ 110 | 111 | # Display crontab rules 112 | - name: Display Crontab Rules 113 | run: sudo crontab -l 114 | 115 | # Purge WireGuard configuration 116 | - name: Purge WireGuard Configuration 117 | run: sudo ./wireguard-manager.sh --purge 118 | 119 | # Uninstall WireGuard Manager 120 | - name: Uninstall WireGuard Manager 121 | run: sudo ./wireguard-manager.sh --uninstall 122 | 123 | # Display Configuration Files 124 | - name: Show Configuration Files 125 | run: | 126 | [ -f /etc/wireguard/wg0.conf ] && cat /etc/wireguard/wg0.conf || echo "wg0.conf not found" 127 | [ -f /etc/unbound/unbound.conf ] && cat /etc/unbound/unbound.conf || echo "unbound.conf not found" 128 | [ -f /var/lib/unbound/root.key ] && cat /var/lib/unbound/root.key || echo "root.key not found" 129 | [ -f /etc/unbound/root.hints ] && cat /etc/unbound/root.hints || echo "root.hints not found" 130 | [ -f /etc/unbound/unbound.conf.d/hosts.conf ] && cat /etc/unbound/unbound.conf.d/hosts.conf || echo "hosts.conf not found" 131 | [ -f /etc/resolv.conf ] && cat /etc/resolv.conf || echo "resolv.conf not found" 132 | for file in /etc/wireguard/clients/*; do 133 | if [ -f "$file" ]; then 134 | echo "Showing $file" 135 | cat "$file" 136 | else 137 | echo "File $file not found" 138 | fi 139 | done 140 | 141 | # Display crontab rules post-uninstallation 142 | - name: Display Crontab Rules Post-Uninstallation 143 | run: sudo crontab -l 144 | 145 | # Final network test 146 | - name: Final Network Test 147 | run: curl "${{ env.IP_SERVICE_URL }}" 148 | -------------------------------------------------------------------------------- /.github/workflows/deploy-github-pages.yml: -------------------------------------------------------------------------------- 1 | # Name of the workflow 2 | name: Deploy files to github pages 3 | 4 | # Define the events that trigger the workflow 5 | on: 6 | # Trigger the workflow on push events 7 | push: 8 | # Only for the main branch 9 | branches: 10 | - "main" 11 | # Only for specific paths 12 | paths: 13 | - "assets/hosts" 14 | - "assets/named.cache" 15 | - "wireguard-manager.sh" 16 | # Allow manual triggering of the workflow 17 | workflow_dispatch: 18 | 19 | # Define the permissions for the workflow 20 | permissions: 21 | # Read access to the repository content 22 | contents: read 23 | # Write access to GitHub Pages 24 | pages: write 25 | # Write access to GitHub ID Tokens 26 | id-token: write 27 | 28 | # Define the concurrency settings for the workflow 29 | concurrency: 30 | # Group name for the concurrency 31 | group: "pages" 32 | # Cancel any in-progress job runs when a new job run is triggered 33 | cancel-in-progress: true 34 | 35 | # Define the jobs in the workflow 36 | jobs: 37 | # Define a job named "deploy" 38 | deploy: 39 | # Define the environment for the job 40 | environment: 41 | # Name of the environment 42 | name: github-pages 43 | # URL of the environment 44 | url: ${{ steps.deployment.outputs.page_url }} 45 | # The type of runner that the job will run on 46 | runs-on: ubuntu-latest 47 | # Define the steps in the job 48 | steps: 49 | # Check out the repository code 50 | - name: Checkout 51 | uses: actions/checkout@v4 52 | # Setup GitHub Pages 53 | - name: Setup Pages 54 | uses: actions/configure-pages@v5 55 | # Upload the repository content as an artifact 56 | - name: Upload artifact 57 | uses: actions/upload-artifact@v4 58 | with: 59 | name: github-pages 60 | path: | 61 | assets/hosts 62 | assets/named.cache 63 | wireguard-manager.sh 64 | # Deploy the artifact to GitHub Pages 65 | - name: Deploy to GitHub Pages 66 | id: deployment 67 | uses: actions/deploy-pages@v4 68 | -------------------------------------------------------------------------------- /.github/workflows/monthly-application-release.yml: -------------------------------------------------------------------------------- 1 | name: Monthly App Release 2 | 3 | on: 4 | schedule: 5 | # Trigger the workflow on the first day of every month at midnight 6 | - cron: "0 0 1 * *" 7 | workflow_dispatch: 8 | 9 | jobs: 10 | release_app: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout Repository 15 | uses: actions/checkout@v4 # Updated to use the latest version for better compatibility and features 16 | 17 | - name: Get Current Date 18 | id: current_date 19 | run: echo "CURRENT_DATE=$(date +'%Y-%m-%d-%H-%M-%S')" >> $GITHUB_ENV 20 | 21 | - name: Create and Publish Release 22 | uses: actions/create-release@v1 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | with: 26 | tag_name: releases-${{ env.CURRENT_DATE }} 27 | release_name: releases-${{ env.CURRENT_DATE }} 28 | draft: false 29 | prerelease: false 30 | -------------------------------------------------------------------------------- /.github/workflows/shell-check-wireguard-manager.yml: -------------------------------------------------------------------------------- 1 | # Name of the workflow 2 | name: ShellCheck WireGuard Manager 3 | 4 | # Define the events that trigger the workflow 5 | on: 6 | # Trigger the workflow on push events and pull request events for changes in .sh files 7 | push: 8 | paths: 9 | - "**.sh" 10 | pull_request: 11 | paths: 12 | - "**.sh" 13 | # Allow manual triggering of the workflow 14 | workflow_dispatch: 15 | 16 | # Define the jobs in the workflow 17 | jobs: 18 | # Define a job named "shellcheck" 19 | shellcheck: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | # Define the steps in the job 23 | steps: 24 | # Check out the repository code 25 | - name: Check out code 26 | uses: actions/checkout@v4 # Use v2 of checkout action for better compatibility and features 27 | # Run shellcheck on the shell scripts 28 | - name: Run ShellCheck 29 | uses: ludeeus/action-shellcheck@v2.0.0 # Use a specific version instead of master 30 | -------------------------------------------------------------------------------- /assets/Wireguard-Manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/complexorganizations/wireguard-manager/e0f481f416d699599a26345e72b1c6f20053bae2/assets/Wireguard-Manager.png -------------------------------------------------------------------------------- /assets/ad-blocker-vs-no-ad-blocker.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/complexorganizations/wireguard-manager/e0f481f416d699599a26345e72b1c6f20053bae2/assets/ad-blocker-vs-no-ad-blocker.mp4 -------------------------------------------------------------------------------- /assets/hosts: -------------------------------------------------------------------------------- 1 | 33across.com 2 | 360yield.com 3 | 3lift.com 4 | aaxads.com 5 | abtasty.com 6 | actonservice.com 7 | acuityplatform.com 8 | ad-stir.com 9 | ad4m.at 10 | adadvisor.net 11 | adblade.com 12 | adcolony.com 13 | addthis.com 14 | adform.net 15 | adgrx.com 16 | adingo.jp 17 | adjust.com 18 | adkernel.com 19 | admanmedia.com 20 | adnxs.com 21 | adobe.io 22 | adobedtm.com 23 | adotmob.com 24 | ads-twitter.com 25 | ads.linkedin.com 26 | adsafeprotected.com 27 | adservice.google.com 28 | adsmoloco.com 29 | adsrvr.org 30 | adsymptotic.com 31 | adtechus.com 32 | adtng.com 33 | advertising.com 34 | agkn.com 35 | airpr.com 36 | alexametrics.com 37 | amazon-adsystem.com 38 | amplitude.com 39 | amung.us 40 | analytics.tiktok.com 41 | analytics.yahoo.com 42 | app-measurement.com 43 | app.link 44 | appcenter.ms 45 | applovin.com 46 | applvn.com 47 | appsflyer.com 48 | attributionapp.com 49 | atwola.com 50 | automatad.com 51 | bazaarvoice.com 52 | beap.gemini.yahoo.com 53 | betrad.com 54 | bid.glass 55 | bidr.io 56 | bidswitch.net 57 | bizible.com 58 | bizographics.com 59 | bluecava.com 60 | bluekai.com 61 | bnmla.com 62 | bounceexchange.com 63 | branch.io 64 | braze.com 65 | brightcove.net 66 | brightline.tv 67 | browser-intake-datadoghq.com 68 | bttrack.com 69 | bugsnag.com 70 | casalemedia.com 71 | chartbeat.com 72 | chartbeat.net 73 | chilipiper.com 74 | clarity.ms 75 | clean.gg 76 | clearbit.com 77 | clearbitjs.com 78 | clickcease.com 79 | clicktale.net 80 | clinch.co 81 | connatix.com 82 | connectad.io 83 | contextweb.com 84 | conviva.com 85 | cookiefirst.com 86 | cookielaw.org 87 | cookiepro.com 88 | crashlytics.com 89 | criteo.com 90 | criteo.net 91 | crowdtwist.com 92 | dap.digitalgov.gov 93 | datadoghq.com 94 | de17a.com 95 | decibelinsight.net 96 | deepintent.com 97 | demandbase.com 98 | demdex.net 99 | dianomi.com 100 | disqus.com 101 | disquscdn.com 102 | districtm.io 103 | doubleclick.net 104 | doubleverify.com 105 | dowjoneson.com 106 | drift.com 107 | driftt.com 108 | dyntrk.com 109 | emxdgt.com 110 | ensighten.com 111 | eqads.com 112 | etahub.com 113 | everesttech.net 114 | exdynsrv.com 115 | exelator.com 116 | exosrv.com 117 | extend.tv 118 | extremereach.io 119 | eyeota.net 120 | facebook.net 121 | feedad.com 122 | firstimpression.io 123 | flashtalking.com 124 | forter.com 125 | fuseplatform.net 126 | fwmrm.net 127 | g2crowd.com 128 | gaconnector.com 129 | geoip-js.com 130 | getblueshift.com 131 | getclicky.com 132 | getdrip.com 133 | getnitropack.com 134 | go-mpulse.net 135 | google-analytics.com 136 | googleadservices.com 137 | googleoptimize.com 138 | googlesyndication.com 139 | googletagmanager.com 140 | grabify.link 141 | gravatar.com 142 | gumgum.com 143 | heapanalytics.com 144 | helpshift.com 145 | hotjar.com 146 | hs-analytics.net 147 | hs-banner.com 148 | hs-scripts.com 149 | hsadspixel.net 150 | hsforms.com 151 | hsleadflows.net 152 | i18n-pglstatp.com 153 | ib-ibi.com 154 | id5-sync.com 155 | igodigital.com 156 | impactradius-event.com 157 | imrworldwide.com 158 | inmobi.com 159 | inner-active.mobi 160 | innovid.com 161 | insightexpressai.com 162 | instabug.com 163 | intellimize.co 164 | intercom.io 165 | iplogger.org 166 | ipredictive.com 167 | ironsrc.mobi 168 | ispot.tv 169 | iterable.com 170 | izooto.com 171 | jivox.com 172 | justpremium.com 173 | kargo.com 174 | kissmetrics.io 175 | launchdarkly.com 176 | leadforensics.com 177 | lfeeder.com 178 | liadm.com 179 | lijit.com 180 | linksynergy.com 181 | listrakbi.com 182 | litix.io 183 | liveramp.com 184 | lkqd.net 185 | loopme.com 186 | luckyorange.com 187 | marketo.net 188 | media.net 189 | media6degrees.com 190 | memoinsights.com 191 | metadsp.co.uk 192 | metrics.icloud.com 193 | metrics.sp0n.io 194 | mfadsrvr.com 195 | mintegral.net 196 | mixpanel.com 197 | ml314.com 198 | moatads.com 199 | moatpixel.com 200 | mookie1.com 201 | mouseflow.com 202 | mparticle.com 203 | mxpnl.com 204 | ndmdhs.com 205 | newrelic.com 206 | newscgp.com 207 | nr-data.net 208 | oath.com 209 | olark.com 210 | omappapi.com 211 | omnitagjs.com 212 | omtrdc.net 213 | onesignal.com 214 | onetrust.com 215 | openx.net 216 | optimizely.com 217 | outbrain.com 218 | pangle.io 219 | parsely.com 220 | perimeterx.com 221 | perimeterx.net 222 | permutive.app 223 | permutive.com 224 | pippio.com 225 | pixel.wp.com 226 | placed.com 227 | platform.twitter.com 228 | plausible.io 229 | popads.net 230 | postrelease.com 231 | primis-amp.tech 232 | privacy-mgmt.com 233 | pro-market.net 234 | ps3cfw.com 235 | pub.network 236 | pubmatic.com 237 | pushengage.com 238 | quantcount.com 239 | quantserve.com 240 | referralcandy.com 241 | refersion.com 242 | requestmetrics.com 243 | researchnow.com 244 | reson8.com 245 | rfihub.com 246 | rlcdn.com 247 | rubiconproject.com 248 | rudderstack.com 249 | sail-horizon.com 250 | sascdn.com 251 | saygames.io 252 | scorecardresearch.com 253 | segment.com 254 | semasio.net 255 | sentry-cdn.com 256 | servebom.com 257 | serving-sys.com 258 | sharethis.com 259 | sharethrough.com 260 | sift.com 261 | siftscience.com 262 | simpli.fi 263 | singular.net 264 | sitescout.com 265 | skimresources.com 266 | smartadserver.com 267 | snapkit.com 268 | sonobi.com 269 | sony.tv 270 | speedcurve.com 271 | sportradarserving.com 272 | spot.im 273 | spotscenered.info 274 | spotxchange.com 275 | springserve.com 276 | stackadapt.com 277 | statcounter.com 278 | stats.wp.com 279 | stickyadstv.com 280 | supersonicads.com 281 | survata.com 282 | taboola.com 283 | tapad.com 284 | tapfiliate.com 285 | taplytics.com 286 | teads.tv 287 | technoratimedia.com 288 | tinypass.com 289 | trackjs.com 290 | trafficfactory.biz 291 | trafficjunky.com 292 | trafficjunky.net 293 | traversedlp.com 294 | tremorhub.com 295 | tribalfusion.com 296 | tru.am 297 | trustarc.com 298 | truste.com 299 | tsyndicate.com 300 | turn.com 301 | tvpixel.com 302 | typekit.net 303 | uniconsent.com 304 | unity3d.com 305 | unrulymedia.com 306 | uplynk.com 307 | uspwidelivd.info 308 | vercel-insights.com 309 | viafoura.co 310 | videoamp.com 311 | vilynx.com 312 | visualwebsiteoptimizer.com 313 | vlitag.com 314 | vungle.com 315 | w55c.net 316 | widget.trustpilot.com 317 | wistia.com 318 | yahoo.net 319 | yahoodns.net 320 | ybp.yahoo.com 321 | yieldoptimizer.com 322 | zdassets.com 323 | zeustechnology.com 324 | zimperium.com 325 | -------------------------------------------------------------------------------- /assets/images/icons/aws.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/icons/digitalocean.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/icons/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/icons/gcp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/icons/linode.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/icons/slack.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/named.cache: -------------------------------------------------------------------------------- 1 | ; This file holds the information on root name servers needed to 2 | ; initialize cache of Internet domain name servers 3 | ; (e.g. reference this file in the "cache . " 4 | ; configuration file of BIND domain name servers). 5 | ; 6 | ; This file is made available by InterNIC 7 | ; under anonymous FTP as 8 | ; file /domain/named.cache 9 | ; on server FTP.INTERNIC.NET 10 | ; -OR- RS.INTERNIC.NET 11 | ; 12 | ; last update: June 26, 2024 13 | ; related version of root zone: 2024062601 14 | ; 15 | ; FORMERLY NS.INTERNIC.NET 16 | ; 17 | . 3600000 NS A.ROOT-SERVERS.NET. 18 | A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4 19 | A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30 20 | ; 21 | ; FORMERLY NS1.ISI.EDU 22 | ; 23 | . 3600000 NS B.ROOT-SERVERS.NET. 24 | B.ROOT-SERVERS.NET. 3600000 A 170.247.170.2 25 | B.ROOT-SERVERS.NET. 3600000 AAAA 2801:1b8:10::b 26 | ; 27 | ; FORMERLY C.PSI.NET 28 | ; 29 | . 3600000 NS C.ROOT-SERVERS.NET. 30 | C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12 31 | C.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2::c 32 | ; 33 | ; FORMERLY TERP.UMD.EDU 34 | ; 35 | . 3600000 NS D.ROOT-SERVERS.NET. 36 | D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13 37 | D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2d::d 38 | ; 39 | ; FORMERLY NS.NASA.GOV 40 | ; 41 | . 3600000 NS E.ROOT-SERVERS.NET. 42 | E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10 43 | E.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:a8::e 44 | ; 45 | ; FORMERLY NS.ISC.ORG 46 | ; 47 | . 3600000 NS F.ROOT-SERVERS.NET. 48 | F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241 49 | F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2f::f 50 | ; 51 | ; FORMERLY NS.NIC.DDN.MIL 52 | ; 53 | . 3600000 NS G.ROOT-SERVERS.NET. 54 | G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4 55 | G.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:12::d0d 56 | ; 57 | ; FORMERLY AOS.ARL.ARMY.MIL 58 | ; 59 | . 3600000 NS H.ROOT-SERVERS.NET. 60 | H.ROOT-SERVERS.NET. 3600000 A 198.97.190.53 61 | H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::53 62 | ; 63 | ; FORMERLY NIC.NORDU.NET 64 | ; 65 | . 3600000 NS I.ROOT-SERVERS.NET. 66 | I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17 67 | I.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fe::53 68 | ; 69 | ; OPERATED BY VERISIGN, INC. 70 | ; 71 | . 3600000 NS J.ROOT-SERVERS.NET. 72 | J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30 73 | J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:c27::2:30 74 | ; 75 | ; OPERATED BY RIPE NCC 76 | ; 77 | . 3600000 NS K.ROOT-SERVERS.NET. 78 | K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129 79 | K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fd::1 80 | ; 81 | ; OPERATED BY ICANN 82 | ; 83 | . 3600000 NS L.ROOT-SERVERS.NET. 84 | L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42 85 | L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:9f::42 86 | ; 87 | ; OPERATED BY WIDE 88 | ; 89 | . 3600000 NS M.ROOT-SERVERS.NET. 90 | M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33 91 | M.ROOT-SERVERS.NET. 3600000 AAAA 2001:dc3::35 92 | ; End of file -------------------------------------------------------------------------------- /assets/readme.md: -------------------------------------------------------------------------------- 1 | # WireGuard Manager Assets 2 | 3 | This directory contains assets for the `wireguard-manager` project. These assets can include images, icons, configuration files, and other static resources that support the main application. 4 | 5 | ## Table of Contents 6 | 7 | - [Overview](#overview) 8 | - [Directory Structure](#directory-structure) 9 | - [Usage](#usage) 10 | - [Contributing](#contributing) 11 | - [License](#license) 12 | 13 | ## Overview 14 | 15 | Assets are an integral part of many projects, providing visual, audio, or other support to the main application. In the context of `wireguard-manager`, these assets might be used for branding, user interface design, or documentation. 16 | 17 | ## Directory Structure 18 | 19 | - **Images/**: Contains images used in the application or documentation. 20 | - **Icons/**: Contains icon files for the application. 21 | - **Configurations/**: Sample or default configuration files for WireGuard setups. 22 | - **Scripts/**: Any auxiliary scripts that might be needed for asset generation or management. 23 | 24 | (Note: The above structure is hypothetical and should be adjusted based on the actual contents of the `assets/` directory.) 25 | 26 | ## Usage 27 | 28 | To use the assets: 29 | 30 | 1. Navigate to the desired sub-directory. 31 | 2. Identify the asset you wish to use. 32 | 3. Integrate or reference it in your application or documentation as needed. 33 | 34 | ## Contributing 35 | 36 | If you'd like to contribute new assets or make changes to existing ones: 37 | 38 | 1. Fork the `wireguard-manager` repository. 39 | 2. Create a new branch for your changes. 40 | 3. Add or modify assets in the `assets/` directory. 41 | 4. Push your changes and create a pull request. 42 | 43 | When contributing, please ensure that you have the rights to any assets you add and that they adhere to the project's licensing. 44 | 45 | ## License 46 | 47 | Unless otherwise specified, the assets in this directory are licensed under the same license as the `wireguard-manager` project. See the [LICENSE](../LICENSE) file in the root directory for more information. 48 | 49 | --- 50 | 51 | This is a basic template and can be expanded upon based on the specific needs and details of the `wireguard-manager` project. Adjustments might be needed based on the actual assets present in the directory and their specific configurations. 52 | -------------------------------------------------------------------------------- /code_of_conduct.md: -------------------------------------------------------------------------------- 1 | # Citizen Code of Conduct 2 | 3 | ## 1. Purpose 4 | 5 | This repository's primary goal is to be inclusive to the most significant number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof). 6 | 7 | This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior. 8 | 9 | We invite all those who participate in this repository to help us create safe and positive experiences. 10 | 11 | ## 2. Open [Source/Culture/Tech] Citizenship 12 | 13 | A supplemental goal of this Code of Conduct is to increase open [source/culture/tech] citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community. 14 | 15 | Communities mirror the societies in which they exist, and affirmative action is essential to counteract the many forms of inequality and abuses of power in society. 16 | 17 | If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know. 18 | 19 | ## 3. Expected Behavior 20 | 21 | The following behaviors are expected and requested of all community members: 22 | 23 | - Participate authentically and actively. In doing so, you contribute to the health and longevity of this community. 24 | - Exercise consideration and respect in your speech and actions. 25 | - Attempt collaboration before conflict. 26 | - Refrain from demeaning, discriminatory, or harassing behavior and speech. 27 | - Be mindful of your surroundings and your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential. 28 | - Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations. 29 | 30 | ## 4. Unacceptable Behavior 31 | 32 | The following behaviors are considered harassment and are unacceptable within our community: 33 | 34 | - Violence, threats of violence or violent language directed against another person. 35 | - Sexist, racist, homophobic, transphobic, ableist, or otherwise discriminatory jokes and language. 36 | - Posting or displaying sexually explicit or violent material. 37 | - Posting or threatening to post other people's personally identifying information ("doxing"). 38 | - Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability. 39 | - Inappropriate photography or recording. 40 | - Inappropriate physical contact. You should have someone's consent before touching them. 41 | - Unwelcome sexual attention. This includes sexualized comments or jokes, inappropriate touching, groping, and unwelcome sexual advances. 42 | - Deliberate intimidation, stalking or following (online or in-person). 43 | - Advocating for, or encouraging, any of the above behavior. 44 | - Sustained disruption of community events, including talks and presentations. 45 | 46 | ## 5. Weapons Policy 47 | 48 | No weapons will be allowed at these repository events, community spaces, or in other areas covered by the scope of this Code of Conduct. Weapons include but are not limited to guns, explosives (including fireworks), and large knives such as those used for hunting or display and any other item used to cause injury or harm to others. Anyone seen in possession of one of these items will be asked to leave immediately, and will only be allowed to return without the weapon. Community members are further expected to comply with all state and local laws on this matter. 49 | 50 | ## 6. Consequences of Unacceptable Behavior 51 | 52 | Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated. 53 | 54 | Anyone asked to stop unacceptable behavior is expected to comply immediately. 55 | 56 | If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, including a temporary ban or permanent expulsion from the community without warning (and without a refund in the case of a paid event). 57 | 58 | ## 7. Reporting Guidelines 59 | 60 | If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. support@complexorganizations.com. 61 | 62 | Additionally, community organizers are available to help community members engage with local law enforcement or to help otherwise those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress. 63 | 64 | ## 8. Addressing Grievances 65 | 66 | If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify complexorganizations with a concise description of your grievance. Your grievance will be handled following our existing governing policies. 67 | 68 | ## 9. Scope 69 | 70 | We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues--online and in-person--as well as in all one-on-one communications about community business. 71 | 72 | This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such action can adversely affect the safety and well-being of community members. 73 | 74 | ## 10. Contact info 75 | 76 | support@complexorganizations.com 77 | 78 | ## 11. License and attribution 79 | 80 | The Citizen Code of Conduct is distributed by [Stumptown Syndicate](http://stumptownsyndicate.org) under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/). 81 | 82 | Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy). 83 | 84 | _Revision 2.3. Posted 6 March 2017._ 85 | 86 | _Revision 2.2. Posted 4 February 2016._ 87 | 88 | _Revision 2.1. Posted 23 June 2014._ 89 | 90 | _Revision 2.0, adopted by the [Stumptown Syndicate](http://stumptownsyndicate.org) board on 10 January 2013. Posted 17 March 2013._ 91 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | **MIT License** 2 | 3 | **Copyright (c) 2023 ComplexOrganizations** 4 | 5 | This license grants everyone a free permission to obtain, use, modify, and distribute this software, referred to as the "Software," along with its documentation. This is allowed without any restrictions, encompassing but not limited to the rights for using, copying, modifying, merging, publishing, distributing, sublicensing, and/or selling copies of the Software. It also permits the Software to be provided to other individuals under these terms. 6 | 7 | These conditions must be followed: 8 | 9 | - Every distribution of the Software or its substantial portions must include the above copyright notice and this permission notice. 10 | 11 | **Disclaimer:** 12 | 13 | The Software is provided "as is," without any warranty of any kind, either expressed or implied. This includes, but is not limited to, implied warranties of merchantability and fitness for a particular purpose. The authors or copyright holders bear no liability for any claims, damages, or other liabilities, whether in an action of contract, tort or otherwise, that arise from, are related to, or are connected with the Software or the use or other dealings in the Software. 14 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # WireGuard-Manager: Secure Your Network 💻 🖥! 2 | 3 | ## 🔰 Introduction 4 | 5 | Welcome to WireGuard-Manager, your solution for setting up WireGuard, a cutting-edge VPN protocol. WireGuard is known for its speed, security, and ease of use, making it an ideal choice for both personal and professional VPN needs. This tool is designed to simplify the installation and management of WireGuard, ensuring a secure and efficient networking experience. 6 | 7 | ## Quality and Reliability 8 | 9 | ### Project Information and Status 10 | 11 | - **Latest Releases**: Stay on top of our newest versions: 12 | [![Latest Release](https://img.shields.io/github/v/release/complexorganizations/wireguard-manager)](https://github.com/complexorganizations/wireguard-manager/releases/latest) 13 | 14 | - **Monthly App Release**: Track our regular monthly releases: 15 | [![Monthly App Release](https://github.com/complexorganizations/wireguard-manager/actions/workflows/monthly-application-release.yml/badge.svg)](https://github.com/complexorganizations/wireguard-manager/actions/workflows/monthly-application-release.yml) 16 | 17 | ### Build Statuses 18 | 19 | - **Code Quality Assurance**: Verified by ShellCheck for reliability: 20 | [![ShellCheck WireGuard Manager](https://github.com/complexorganizations/wireguard-manager/actions/workflows/shell-check-wireguard-manager.yml/badge.svg)](https://github.com/complexorganizations/wireguard-manager/actions/workflows/shell-check-wireguard-manager.yml) 21 | 22 | - **Blocked Hosts**: Monitor the status of blocked host updates: 23 | [![Blocked Hosts Update Status](https://github.com/complexorganizations/wireguard-manager/actions/workflows/auto-update-blocked-hosts.yaml/badge.svg)](https://github.com/complexorganizations/wireguard-manager/actions/workflows/auto-update-blocked-hosts.yaml) 24 | 25 | - **Named Cache**: Check updates for named cache: 26 | [![Named Cache Update Status](https://github.com/complexorganizations/wireguard-manager/actions/workflows/auto-update-named-cache.yml/badge.svg)](https://github.com/complexorganizations/wireguard-manager/actions/workflows/auto-update-named-cache.yml) 27 | 28 | - **Software Updates**: Keep track of the latest software builds: 29 | [![Software Build Status](https://github.com/complexorganizations/wireguard-manager/actions/workflows/build-latest-version.yml/badge.svg)](https://github.com/complexorganizations/wireguard-manager/actions/workflows/build-latest-version.yml) 30 | 31 | ### Contribution and Issues 32 | 33 | - **Open Issues Tracking**: View and address current open issues: 34 | [![Open Issues](https://img.shields.io/github/issues/complexorganizations/wireguard-manager)](https://github.com/complexorganizations/wireguard-manager/issues) 35 | 36 | - **Contribution Opportunities**: Dive into open pull requests and contribute: 37 | [![Active Pull Requests](https://img.shields.io/github/issues-pr/complexorganizations/wireguard-manager)](https://github.com/complexorganizations/wireguard-manager/pulls) 38 | 39 | ### Licensing 40 | 41 | - **Project License**: Our work is under the Apache 2.0 License: 42 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/complexorganizations/wireguard-manager/blob/main/license.md) 43 | 44 | ## ✊ Show Your Support 45 | 46 | If you've found this project useful, please consider giving it a star and forking it. Your support is greatly appreciated! 47 | 48 | ## 🤷 What is VPN? 49 | 50 | A Virtual Private Network (VPN) allows users to send and receive data through shared or public networks as if their computing devices were directly connected to the private network. Thus, applications running on an end-system (PC, smartphone, etc.) over a VPN may benefit from individual network features, protection, and management. Encryption is a standard aspect of a VPN connection but not an intrinsic one. 51 | 52 | ## 📶 What is WireGuard? 53 | 54 | WireGuard is a straightforward yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. WireGuard is designed as a general-purpose VPN for running on embedded interfaces and super computers alike, fit for many circumstances. Initially released for the Linux kernel, it is now cross-platform (Windows, macOS, BSD, iOS, Android) and widely deployable. It is currently under a massive development, but it already might be regarded as the most secure, most comfortable to use, and the simplest VPN solution in the industry. 55 | 56 | ## Why WireGuard-Manager? 57 | 58 | - **Security First**: With top-notch encryption and privacy features. 59 | - **User-Friendly**: Easy to install and manage, regardless of your tech-savviness. 60 | - **High Performance**: Enjoy fast and reliable connections. 61 | - **Open Source**: Built and improved by the community. 62 | 63 | ## ⛳ Goals 64 | 65 | - Robust and modern security as a standard. 66 | - Minimal configuration with essential management tools. 67 | - Optimal performance for both low-latency and high-bandwidth operations. 68 | - Simplified command-line interface for easy integration with system networking. 69 | 70 | ## 🌲 Prerequisite 71 | 72 | - Supported on a variety of systems including Alma, Alpine, Arch, CentOS, Debian, Fedora, FreeBSD, Kali, Mint, Manjaro, Neon, Oracle, Pop, Raspbian, RHEL, Rocky, Ubuntu, and more. 73 | - Requires Linux Kernel 3.1 or newer. 74 | - Superuser access or a user account with `sudo` privileges is necessary. 75 | 76 | ## 🚦 Getting Started 77 | 78 | 1. **Installation**: Simple and quick installation process. 79 | 2. **Configuration**: Easy-to-follow configuration steps. 80 | 3. **Management**: User-friendly interface for managing your VPN. 81 | 82 | ## Installation Guide 83 | 84 | https://github.com/complexorganizations/wireguard-manager/assets/102563715/dd539835-2c30-4146-b4f8-940329aa6070 85 | 86 | ## 🐧 Installation 87 | 88 | To ensure the successful installation of the WireGuard Manager script on various Linux systems, it's crucial to have `curl` and `bash` installed. Here's an expanded installation guide that includes instructions for installing `curl` and `bash` on different Linux distributions: 89 | 90 | ### Installing `curl` & `bash` & `resolvconf` on Linux Systems 91 | 92 | #### Debian/Ubuntu-based Systems (e.g., Ubuntu, Debian, Linux Mint): 93 | 94 | ```bash 95 | sudo apt update 96 | sudo apt install curl bash resolvconf 97 | ``` 98 | 99 | #### Red Hat-based Systems (e.g., CentOS, RHEL, Fedora): 100 | 101 | ```bash 102 | sudo yum install curl bash resolvconf 103 | ``` 104 | 105 | or 106 | 107 | ```bash 108 | sudo dnf install curl bash resolvconf 109 | ``` 110 | 111 | #### Arch-based Systems (e.g., Arch Linux, Manjaro): 112 | 113 | ```bash 114 | sudo pacman -Sy curl bash resolvconf 115 | ``` 116 | 117 | #### Alpine Linux: 118 | 119 | ```bash 120 | sudo apk update 121 | sudo apk add curl bash resolvconf 122 | ``` 123 | 124 | #### Other Distributions: 125 | 126 | For other Linux distributions, you can use the package manager specific to that distribution to install `curl` & `bash` & `resolvconf`. The package names may vary slightly. 127 | 128 | ### Installing WireGuard Manager Script 129 | 130 | Now that you have `curl` and `bash` installed, you can proceed with installing the WireGuard Manager script using the provided instructions: 131 | 132 | 1. First, use `curl` to download the script and save it in `/usr/local/bin/`: 133 | 134 | ```bash 135 | curl https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/wireguard-manager.sh --create-dirs -o /usr/local/bin/wireguard-manager.sh 136 | ``` 137 | 138 | 2. Next, make the script user executable: 139 | 140 | ```bash 141 | chmod +x /usr/local/bin/wireguard-manager.sh 142 | ``` 143 | 144 | 3. Finally, execute the script: 145 | 146 | ```bash 147 | bash /usr/local/bin/wireguard-manager.sh 148 | ``` 149 | 150 | ### Connecting to WireGuard Interface 151 | 152 | In your `/etc/wireguard/clients` directory, you will find `.conf` files. These are the peer configuration files. Download them from your WireGuard Interface and connect using your favorite WireGuard Peer. 153 | 154 | ## 🔑 Usage 155 | 156 | ```md 157 | usage: bash /usr/local/bin/wireguard-manager.sh # --install 158 | --install Installs the WireGuard interface on your system 159 | --start Starts the WireGuard interface if it's not already running 160 | --stop Stops the WireGuard interface if it's currently running 161 | --restart Restarts the WireGuard interface 162 | --list Lists all the peers currently connected to the WireGuard interface 163 | --add Adds a new peer to the WireGuard interface 164 | --remove Removes a specified peer from the WireGuard interface 165 | --reinstall Reinstalls the WireGuard interface, keeping the current configuration 166 | --uninstall Uninstalls the WireGuard interface from your system 167 | --update Updates the WireGuard Manager to the latest version 168 | --ddns Updates the IP address of the WireGuard interface using Dynamic DNS 169 | --backup Creates a backup of your current WireGuard configuration 170 | --restore Restores the WireGuard configuration from a previous backup 171 | --purge Removes all peers from the WireGuard interface 172 | --help Displays this usage guide 173 | ``` 174 | 175 | ## 🥰 Features 176 | 177 | - Seamless installation and configuration of WireGuard Interface 178 | - Convenient backup and restoration of WireGuard 179 | - Automatic expiration of peer configurations 180 | - Support for both IPv4 and IPv6, with leak protection 181 | - Variety of public DNS options available for peers 182 | - Option to use a self-hosted resolver with Unbound for DNS leak prevention and DNSSEC support 183 | - Effortless management of Nftables rules and forwarding 184 | - Easy removal and uninstallation of WireGuard Interface 185 | - Mandatory preshared-key for an additional layer of security 186 | - Numerous other minor features for enhanced user experience 187 | 188 | ## 💡 Configuration Options 189 | 190 | - `PRIVATE_SUBNET_V4_SETTINGS`: This defines the private IPv4 subnet used within the VPN. The default is `10.0.0.0/8`, a standard private IP range. 191 | - `PRIVATE_SUBNET_V6_SETTINGS`: This sets the private IPv6 subnet. The default `fd00:00:00::0/8` is a typical private IPv6 range. 192 | - `SERVER_HOST_V4_SETTINGS`: This is used to detect the public IPv4 address of the server, crucial for establishing connections from outside the local network. 193 | - `SERVER_HOST_V6_SETTINGS`: This is the IPv6 counterpart to the previous setting, used for detecting the server's public IPv6 address. 194 | - `SERVER_PUB_NIC_SETTINGS`: This determines the local public network interface using the `ip` command, essential for server communication on the public network. 195 | - `SERVER_PORT_SETTINGS`: This specifies the default public port (`51820`) for the WireGuard interface, the port through which VPN traffic will pass. 196 | - `NAT_CHOICE_SETTINGS`: This configures the use of the VPN tunnel's keep-alive feature, which helps keep the connection active. 197 | - `MTU_CHOICE_SETTINGS`: This sets the Maximum Transmission Unit (MTU) for WireGuard peers, impacting the size of packets transmitted over the network. 198 | - `SERVER_HOST_SETTINGS`: This is a general setting for defining server-specific configurations. 199 | - `CLIENT_ALLOWED_IP_SETTINGS`: This defines the IP range allowed for clients connecting to the VPN, restricting which devices can connect. 200 | - `AUTOMATIC_UPDATES_SETTINGS`: This likely relates to whether the system will automatically update software or configurations. 201 | - `AUTOMATIC_BACKUP_SETTINGS`: This pertains to the automatic backup of system configurations or data. 202 | - `DNS_PROVIDER_SETTINGS`: This involves setting up a DNS provider for the network. If you're not using Unbound, you'll need to specify another DNS service. 203 | - `CONTENT_BLOCKER_SETTINGS`: This might relate to settings for blocking certain types of content through the network. 204 | - `CLIENT_NAME`: This is the name assigned to a WireGuard peer (client) in the VPN. 205 | - `AUTOMATIC_CONFIG_REMOVER`: This is possibly a setting to automatically remove certain configurations after they are no longer needed or after a set period. 206 | 207 | ## 👉👈 Compatibility with Linux Distributions 208 | 209 | | Operating System | i386 Support | amd64 Support | armhf Support | arm64 Support | 210 | | ------------------- | ------------ | ------------- | ------------- | ------------- | 211 | | Ubuntu 14 and below | No | No | No | No | 212 | | Ubuntu 16 and above | Yes | Yes | Yes | Yes | 213 | | Debian 7 and below | No | No | No | No | 214 | | Debian 8 and above | Yes | Yes | Yes | Yes | 215 | | CentOS 6 and below | No | No | No | No | 216 | | CentOS 7 and above | Yes | Yes | Yes | Yes | 217 | | Fedora 29 and below | No | No | No | No | 218 | | Fedora 30 and above | Yes | Yes | Yes | Yes | 219 | | RedHat 6 and below | No | No | No | No | 220 | | RedHat 7 and above | Yes | Yes | Yes | Yes | 221 | | Kali 1.0 and below | No | No | No | No | 222 | | Kali 1.1 and above | Yes | Yes | Yes | Yes | 223 | | Arch Linux | Yes | Yes | Yes | Yes | 224 | | Raspbian | Yes | Yes | Yes | Yes | 225 | | PopOS | Yes | Yes | Yes | Yes | 226 | | Manjaro | Yes | Yes | Yes | Yes | 227 | | Mint | Yes | Yes | Yes | Yes | 228 | | AlmaLinux | Yes | Yes | Yes | Yes | 229 | | Alpine | Yes | Yes | Yes | Yes | 230 | | FreeBSD | Yes | Yes | Yes | Yes | 231 | | KDE Neon | Yes | Yes | Yes | Yes | 232 | | Rocky Linux | Yes | Yes | Yes | Yes | 233 | | Oracle Linux | Yes | Yes | Yes | Yes | 234 | 235 | ## ☁️ Compatibility with Cloud Providers 236 | 237 | | Cloud | Supported | 238 | | --------------- | --------- | 239 | | AWS | Yes | 240 | | Google Cloud | Yes | 241 | | Linode | Yes | 242 | | Digital Ocean | Yes | 243 | | Vultr | Yes | 244 | | Microsoft Azure | Yes | 245 | | OpenStack | Yes | 246 | | Rackspace | Yes | 247 | | Scaleway | Yes | 248 | | EuroVPS | Yes | 249 | | Hetzner Cloud | No | 250 | | Strato | No | 251 | 252 | ## 🛡️ Compatibility with Virtualization 253 | 254 | | Virtualization | Supported | 255 | | -------------- | --------- | 256 | | KVM | Yes | 257 | | None | Yes | 258 | | Qemu | Yes | 259 | | LXC | Yes | 260 | | Microsoft | Yes | 261 | | Vmware | Yes | 262 | | OpenVZ | No | 263 | | Docker | No | 264 | | WSL | No | 265 | 266 | ## 💻 Compatibility with Linux Kernel 267 | 268 | | Kernel | Compatibility | 269 | | -------------------------- | ------------- | 270 | | Linux Kernel 3.0 and below | No | 271 | | Linux Kernel 3.1 and above | Yes | 272 | 273 | ## 🙋 Frequently Asked Questions 274 | 275 | **Which hosting providers do you recommend?** 276 | 277 | - **Google Cloud**: Provides global locations and IPv4 support, with prices starting at $3.50/month. [Visit Google Cloud](https://cloud.google.com) 278 | - **Amazon Web Services (AWS)**: Offers global locations and IPv4 support, with plans starting from $5.00/month. [Visit AWS](https://aws.amazon.com) 279 | - **Microsoft Azure**: Features worldwide locations and IPv4 support, with plans beginning at $5.00/month. [Visit Azure](https://azure.microsoft.com) 280 | - **Linode**: Includes global locations, supports both IPv4 & IPv6, starting at $5.00/month. [Visit Linode](https://www.linode.com) 281 | - **Vultr**: Provides worldwide locations, supports IPv4 & IPv6, with prices starting at $3.50/month. [Visit Vultr](https://www.vultr.com) 282 | 283 | **Which WireGuard clients do you recommend?** 284 | 285 | - **Windows**: You can download WireGuard from their [official website](https://www.wireguard.com/install). 286 | - **Android**: WireGuard is available on the [Google Play Store](https://play.google.com/store/apps/details?id=com.wireguard.android). 287 | - **macOS**: You can download WireGuard from the [Mac App Store](https://itunes.apple.com/us/app/wireguard/id1451685025). 288 | - **iOS**: WireGuard is available on the [App Store](https://itunes.apple.com/us/app/wireguard/id1441195209). 289 | 290 | ## Additional Information 291 | 292 | **Where can I access comprehensive WireGuard documentation?** 293 | 294 | - The [WireGuard Manual](https://www.wireguard.com) provides detailed information on all available options. 295 | 296 | **How can I install WireGuard without interactive prompts for a headless installation?** 297 | 298 | - Execute the command: `./wireguard-manager.sh --install` 299 | 300 | **Are there any alternatives to self-hosting a VPN?** 301 | 302 | - Yes, [CloudFlare Warp](https://1.1.1.1) is a viable alternative. 303 | 304 | **Why is all the code centralized in one place?** 305 | 306 | - Consider it like a universal remote: it's more efficient to have a single device (or codebase) that performs all functions than having multiple specialized ones. 307 | 308 | **Which port and protocol does WireGuard require?** 309 | 310 | - You need to forward your chosen port or the default port `51820` using the UDP protocol. 311 | 312 | **Do I need to forward any ports for Unbound?** 313 | 314 | - No, port forwarding isn't necessary for Unbound as DNS traffic is routed through the VPN (`port 53`). 315 | 316 | **What does the content blocker restrict?** 317 | 318 | - The content blocker restricts ads, trackers, malware, and phishing attempts. 319 | 320 | **What information is collected and how is it used?** 321 | 322 | - No logs or data are collected or retained. All operations are performed within the system, with no external log transmission. 323 | 324 | ## Setting Up Your Own VPN Server 325 | 326 | To set up your own VPN server, you will need the following items: 327 | 328 | ### Raspberry Pi 5 Setup Components 329 | 330 | - **Raspberry Pi 5**: [View Product](https://www.raspberrypi.com/products/raspberry-pi-5/) 331 | - **Raspberry Pi Case**: [View Product](https://www.raspberrypi.com/products/raspberry-pi-5-case/) 332 | - **Raspberry Pi Active Cooler**: [View Product](https://www.raspberrypi.com/products/active-cooler) 333 | - **Raspberry Pi USB-C Power Supply**: [View Product](https://www.raspberrypi.com/products/27w-power-supply/) 334 | - **Micro SD Card**: [View on Amazon](https://www.amazon.com/dp/B06XWMQ81P) 335 | - **Ethernet Cable**: [View on Amazon](https://www.amazon.com/dp/B00N2VIALK) 336 | - **SD Card Reader**: [View on Amazon](https://www.amazon.com/dp/B0957HQ4D1) 337 | 338 | ### Estimated Cost for Building Your Own VPN 339 | 340 | - The estimated one-time hardware cost is around $100 USD. Please note that there will be ongoing costs for electricity and internet. 341 | 342 | ## WireGuard Resources 343 | 344 | - Homepage: [WireGuard Official Site](https://www.wireguard.com) 345 | - Installation Guide: [Install WireGuard](https://www.wireguard.com/install/) 346 | - Quick Start: [WireGuard QuickStart](https://www.wireguard.com/quickstart/) 347 | - Compilation Instructions: [Compile WireGuard](https://www.wireguard.com/compilation/) 348 | - Whitepaper: [WireGuard Whitepaper](https://www.wireguard.com/papers/wireguard.pdf) 349 | 350 | ## VPN Speed Comparison 351 | 352 | This section compares the internet speed differences between using no VPN, WireGuard, and OpenVPN. 353 | 354 | ### No VPN (Normal Connection) 355 | 356 | ![No VPN Speed Test](https://www.speedtest.net/result/15776043000.png) 357 | 358 | ### WireGuard Speed Test 359 | 360 | ![Wireguard Speed Test](https://www.speedtest.net/result/15776045897.png) 361 | 362 | ### OpenVPN Speed Test 363 | 364 | ![OpenVPN Speed Test](https://www.speedtest.net/result/15593895433.png) 365 | 366 | ## 🙅 Content-Blocking vs. No Content-Blocking 367 | 368 | https://user-images.githubusercontent.com/16564273/125283630-9845d180-e2e6-11eb-8b7d-f30a8f2eae8a.mp4 369 | 370 | ## 📐 Architecture 371 | 372 | ![Wireguard Manager Architecture](https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/assets/Wireguard-Manager.png) 373 | 374 | ## 🤝 Code Development 375 | 376 | **Develop Code Without Cloning the Repository** 377 | 378 | You can directly work on the code without the need to clone the repository. This is facilitated by Visual Studio Code's online platform. By clicking the link below, you can preview and edit the code in your browser, leveraging the intuitive interface of Visual Studio Code. This method streamlines the development process, particularly for those who want to make quick modifications or do not wish to set up the entire repository on their local machine. 379 | 380 | [![Open in Visual Studio Code](https://img.shields.io/badge/preview%20in-vscode.dev-blue)](https://open.vscode.dev/complexorganizations/wireguard-manager) 381 | 382 | ## 🐛 Code Debugging 383 | 384 | **Detailed Debugging Process After Cloning the Repository** 385 | 386 | For a comprehensive debugging process, you might want to clone the repository to your local system. This method allows you to thoroughly test and debug the code in your environment. Follow these steps to clone the repository and start the debugging process: 387 | 388 | 1. **Clone the Repository**: Use the Git command to clone the repository to your preferred directory, such as `/root/` in this example. This step copies all the code from the online repository to your local machine. 389 | 390 | ```bash 391 | git clone https://github.com/complexorganizations/wireguard-manager /root/ 392 | ``` 393 | 394 | 2. **Start Debugging**: After cloning, navigate to the script's directory and initiate the debugging process. The script will be executed in debug mode, providing detailed output of each step. This output is redirected to a log file for easier examination. The log file, located in the same directory, stores all the debugging information, making it easy to trace any issues or understand the script's behavior. 395 | 396 | ```bash 397 | bash -x /root/wireguard-manager/wireguard-manager.sh >>/root/wireguard-manager/wireguard-manager.log 398 | ``` 399 | 400 | Following these steps, you can either quickly modify the code online without cloning or perform a more comprehensive debugging process by cloning the repository to your local machine. Each method offers different benefits depending on your needs and the extent of your work with the WireGuard Manager script. 401 | 402 | ### Detailed Debugging Guide for WireGuard Manager 403 | 404 | 1. **Setting Up the Environment** 405 | 406 | - Ensure that all necessary software, including Git, Bash, and any dependencies required by WireGuard Manager, are installed on your system. 407 | - While Visual Studio Code is used in this example, you can use any IDE that supports Git and Bash. 408 | 409 | 2. **Cloning the Repository** 410 | 411 | - Use Git to clone the WireGuard Manager repository to a local directory: `git clone https://github.com/complexorganizations/wireguard-manager /path/to/local-directory` 412 | - Avoid using root directories for development. Choose a user directory for better safety and permission management. 413 | 414 | 3. **Understanding the Codebase** 415 | 416 | - Review the code to understand its structure, conventions, and documentation. 417 | - Check for a README file or wiki pages in the repository that might provide insights into the codebase. 418 | 419 | 4. **Setting Up Debugging Tools** 420 | 421 | - Configure the debugging tools in your IDE. Set breakpoints, watch variables, and use step-through debugging features. 422 | - Ensure that logging is correctly set up in the script to capture sufficient details for debugging. 423 | 424 | 5. **Running the Script in Debug Mode** 425 | 426 | - Run the script with `bash -x` to get detailed trace outputs: `bash -x /path/to/local-directory/wireguard-manager/wireguard-manager.sh >> /path/to/local-directory/wireguard-manager.log` 427 | - Regularly check the log file for errors or unexpected behavior. 428 | 429 | 6. **Testing in Different Environments** 430 | 431 | - Test the script in isolated environments like Docker containers or VMs to understand its behavior in different settings. 432 | - If possible, test on different operating systems to ensure compatibility. 433 | 434 | 7. **Collaborating and Seeking Feedback** 435 | 436 | - Commit changes to a new branch and use pull requests for reviews. 437 | - Request code reviews from peers to get different perspectives on potential issues. 438 | 439 | 8. **Documenting Your Findings** 440 | 441 | - If you discover undocumented behavior or fixes, update the project documentation. 442 | - Use the repository's issue tracker to report bugs or suggest enhancements. 443 | 444 | 9. **Automating Testing** 445 | 446 | - Create automated tests for critical functionalities to catch bugs early. 447 | - Use CI tools to automate testing with every commit or pull request. 448 | 449 | 10. **Staying Updated with the Repository** 450 | - Regularly update your local repository with changes from the main project to stay in sync and avoid conflicts. 451 | 452 | By following these steps and adapting them to their own development environment and workflow, developers can more effectively debug and contribute to the WireGuard Manager project. This comprehensive approach caters to various skill levels and preferences, thereby facilitating a more inclusive and efficient development process. 453 | 454 | ## 💋 Acknowledgements 455 | 456 | This project is made possible thanks to the Open Source Community. 457 | 458 | ## 📱 Community and Contributions 459 | 460 | Join our community on [![Discord](https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/assets/images/icons/discord.svg)](https://discord.gg/CdjBYMScMS) and [![Slack](https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/assets/images/icons/slack.svg)](https://join.slack.com/t/complexorgani-w5b4873/shared_invite/zt-2e9gz2wh2-dWuylZLgaEgFywNKF_iQRQ) to contribute to the project, share ideas, and get help. 461 | 462 | ## 🤝 Sponsors 463 | 464 | This project is sponsored by 465 | 466 | [![Digital Ocean](https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/assets/images/icons/digitalocean.svg)](https://www.digitalocean.com) [![Google Cloud](https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/assets/images/icons/gcp.svg)](https://cloud.google.com) [![AWS](https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/assets/images/icons/aws.svg)](https://aws.amazon.com) [![Linode](https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/assets/images/icons/linode.svg)](https://linode.com) 467 | 468 | ## Backup 469 | 470 | https://gitlab.com/complexorganizations/wireguard-manager 471 | 472 | ## 📝 License 473 | 474 | WireGuard-Manager is licensed under the Apache License Version 2.0. For more details, please refer to our [License File](https://github.com/complexorganizations/wireguard-manager/blob/main/license.md). 475 | -------------------------------------------------------------------------------- /security.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ### Reporting a Vulnerability 4 | 5 | It is difficult to underestimate the essential importance of Responsible Disclosure when it comes to private communications within the public network area. The lives of some people rely on keeping their experiences secret. On a larger scale than the individual level, entire countries will depend on the protection and dignity of people who manage these projects. Please be prompt in documentation and vulnerability disclosures. 6 | 7 | We'll seek to reach a 90-day turnaround on vulnerabilities that have been reported responsibly. When we haven't updated the repository in 90 days from the audit, disclosing the vulnerability on the GitHub Issues is necessary so others know they can no longer trust this repository to effectively protect their security. 8 | 9 | By default rationale on how software releases should be delivered, we aim for the highest possible level on protection without compromising on the works. Unless the guard may be removed between now and the time you passed away, we believe that this is not enough for our designs. 10 | -------------------------------------------------------------------------------- /wireguard-manager.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # WireGuard-Manager Installation Script 4 | # Purpose: This script automates the installation of WireGuard-Manager, a comprehensive tool for managing WireGuard VPN configurations. 5 | # Author: ComplexOrganizations 6 | # Repository: https://github.com/complexorganizations/wireguard-manager 7 | 8 | # Usage Instructions: 9 | # 1. System Requirements: Ensure you have 'curl' installed on your system. This script is compatible with most Linux distributions. 10 | # 2. Downloading the Script: 11 | # - Use the following command to download the script: 12 | # curl https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/wireguard-manager.sh --create-dirs -o /usr/local/bin/wireguard-manager.sh 13 | # 3. Making the Script Executable: 14 | # - Grant execution permissions to the script: 15 | # chmod +x /usr/local/bin/wireguard-manager.sh 16 | # 4. Running the Script: 17 | # - Execute the script with root privileges: 18 | # bash /usr/local/bin/wireguard-manager.sh 19 | # 5. Follow the on-screen instructions to complete the installation of WireGuard-Manager. 20 | 21 | # Advanced Usage: 22 | # - The script supports various command-line arguments for custom installations. Refer to the repository's readme.md for more details. 23 | # - For automated deployments, environment variables can be set before running this script. 24 | 25 | # Troubleshooting: 26 | # - If you encounter issues, ensure your system is up-to-date and retry the installation. 27 | # - For specific errors, refer to the 'Troubleshooting' section in the repository's documentation. 28 | 29 | # Contributing: 30 | # - Contributions to the script are welcome. Please follow the contributing guidelines in the repository. 31 | 32 | # Contact Information: 33 | # - For support, feature requests, or bug reports, please open an issue on the GitHub repository. 34 | 35 | # License: MIT License 36 | 37 | # Note: This script is provided 'as is', without warranty of any kind. The user is responsible for understanding the operations and risks involved. 38 | 39 | # Check if the script is running as root 40 | function check_root() { 41 | if [ "$(id -u)" -ne 0 ]; then 42 | echo "Error: This script must be run as root." 43 | exit 1 44 | fi 45 | } 46 | 47 | # Call the function to check root privileges 48 | check_root 49 | 50 | # Function to gather current system details 51 | function system-information() { 52 | # This function fetches the ID, version, and major version of the current system 53 | if [ -f /etc/os-release ]; then 54 | # If /etc/os-release file is present, source it to obtain system details 55 | # shellcheck source=/dev/null 56 | source /etc/os-release 57 | CURRENT_DISTRO=${ID} # CURRENT_DISTRO holds the system's ID 58 | CURRENT_DISTRO_VERSION=${VERSION_ID} # CURRENT_DISTRO_VERSION holds the system's VERSION_ID 59 | CURRENT_DISTRO_MAJOR_VERSION=$(echo "${CURRENT_DISTRO_VERSION}" | cut --delimiter="." --fields=1) # CURRENT_DISTRO_MAJOR_VERSION holds the major version of the system (e.g., "16" for Ubuntu 16.04) 60 | fi 61 | } 62 | 63 | # Invoke the system-information function 64 | system-information 65 | 66 | # Define a function to check system requirements 67 | function installing-system-requirements() { 68 | # Check if the current Linux distribution is supported 69 | if { [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "raspbian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ] || [ "${CURRENT_DISTRO}" == "fedora" ] || [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "rhel" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ] || [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ] || [ "${CURRENT_DISTRO}" == "alpine" ] || [ "${CURRENT_DISTRO}" == "freebsd" ] || [ "${CURRENT_DISTRO}" == "ol" ]; }; then 70 | # Check if required packages are already installed 71 | if { [ ! -x "$(command -v curl)" ] || [ ! -x "$(command -v cut)" ] || [ ! -x "$(command -v jq)" ] || [ ! -x "$(command -v ip)" ] || [ ! -x "$(command -v lsof)" ] || [ ! -x "$(command -v cron)" ] || [ ! -x "$(command -v awk)" ] || [ ! -x "$(command -v ps)" ] || [ ! -x "$(command -v grep)" ] || [ ! -x "$(command -v qrencode)" ] || [ ! -x "$(command -v sed)" ] || [ ! -x "$(command -v zip)" ] || [ ! -x "$(command -v unzip)" ] || [ ! -x "$(command -v openssl)" ] || [ ! -x "$(command -v nft)" ] || [ ! -x "$(command -v ifup)" ] || [ ! -x "$(command -v chattr)" ] || [ ! -x "$(command -v gpg)" ] || [ ! -x "$(command -v systemd-detect-virt)" ]; }; then 72 | # Install required packages depending on the Linux distribution 73 | if { [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "raspbian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ]; }; then 74 | apt-get update 75 | apt-get install curl coreutils jq iproute2 lsof cron gawk procps grep qrencode sed zip unzip openssl nftables ifupdown e2fsprogs gnupg systemd -y 76 | elif { [ "${CURRENT_DISTRO}" == "fedora" ] || [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "rhel" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 77 | yum check-update 78 | if [ "${CURRENT_DISTRO}" == "centos" ] && [ "${CURRENT_DISTRO_MAJOR_VERSION}" -ge 7 ]; then 79 | yum install epel-release elrepo-release -y 80 | fi 81 | if [ "${CURRENT_DISTRO}" == "centos" ] && [ "${CURRENT_DISTRO_MAJOR_VERSION}" == 7 ]; then 82 | yum install yum-plugin-elrepo -y 83 | fi 84 | yum install curl coreutils jq iproute lsof cronie gawk procps-ng grep qrencode sed zip unzip openssl nftables NetworkManager e2fsprogs gnupg systemd -y 85 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 86 | pacman -Sy --noconfirm archlinux-keyring 87 | pacman -Su --noconfirm --needed curl coreutils jq iproute2 lsof cronie gawk procps-ng grep qrencode sed zip unzip openssl nftables ifupdown e2fsprogs gnupg systemd 88 | elif [ "${CURRENT_DISTRO}" == "alpine" ]; then 89 | apk update 90 | apk add curl coreutils jq iproute2 lsof cronie gawk procps grep sed zip unzip openssl nftables e2fsprogs gnupg 91 | # apk add curl coreutils jq iproute2 lsof cronie gawk procps grep qrencode sed zip unzip openssl nftables ifupdown e2fsprogs gnupg systemd 92 | elif [ "${CURRENT_DISTRO}" == "freebsd" ]; then 93 | pkg update 94 | pkg install curl coreutils jq iproute2 lsof cronie gawk procps grep qrencode sed zip unzip openssl nftables ifupdown e2fsprogs gnupg systemd 95 | elif [ "${CURRENT_DISTRO}" == "ol" ]; then 96 | yum check-update 97 | yum install curl coreutils jq iproute lsof cronie gawk procps-ng grep qrencode sed zip unzip openssl nftables NetworkManager e2fsprogs gnupg systemd -y 98 | fi 99 | fi 100 | else 101 | echo "Error: Your current distribution ${CURRENT_DISTRO} version ${CURRENT_DISTRO_VERSION} is not supported by this script. Please consider updating your distribution or using a supported one." 102 | exit 103 | fi 104 | } 105 | 106 | # Call the function to check for system requirements and install necessary packages if needed 107 | installing-system-requirements 108 | 109 | # Checking For Virtualization 110 | function virt-check() { 111 | # This code checks if the system is running in a supported virtualization. 112 | # It returns the name of the virtualization if it is supported, or "none" if 113 | # it is not supported. This code is used to check if the system is running in 114 | # a virtual machine, and if so, if it is running in a supported virtualization. 115 | # systemd-detect-virt is a utility that detects the type of virtualization 116 | # that the system is running on. It returns a string that indicates the name 117 | # of the virtualization, such as "kvm" or "vmware". 118 | CURRENT_SYSTEM_VIRTUALIZATION=$(systemd-detect-virt) 119 | # This case statement checks if the virtualization that the system is running 120 | # on is supported. If it is not supported, the script will print an error 121 | # message and exit. 122 | case ${CURRENT_SYSTEM_VIRTUALIZATION} in 123 | "kvm" | "none" | "qemu" | "lxc" | "microsoft" | "vmware" | "xen" | "amazon" | "docker") ;; 124 | *) 125 | echo "Error: the ${CURRENT_SYSTEM_VIRTUALIZATION} virtualization is currently not supported. Please stay tuned for future updates." 126 | exit 127 | ;; 128 | esac 129 | } 130 | 131 | # Call the virt-check function to check for supported virtualization. 132 | virt-check 133 | 134 | # The following function checks the kernel version. 135 | function kernel-check() { 136 | CURRENT_KERNEL_VERSION=$(uname --kernel-release | cut --delimiter="." --fields=1-2) 137 | # Get the current kernel version and extract the major and minor version numbers. 138 | CURRENT_KERNEL_MAJOR_VERSION=$(echo "${CURRENT_KERNEL_VERSION}" | cut --delimiter="." --fields=1) 139 | # Extract the major version number from the current kernel version. 140 | CURRENT_KERNEL_MINOR_VERSION=$(echo "${CURRENT_KERNEL_VERSION}" | cut --delimiter="." --fields=2) 141 | # Extract the minor version number from the current kernel version. 142 | ALLOWED_KERNEL_VERSION="3.1" 143 | # Set the minimum allowed kernel version to 3.1.0. 144 | ALLOWED_KERNEL_MAJOR_VERSION=$(echo ${ALLOWED_KERNEL_VERSION} | cut --delimiter="." --fields=1) 145 | # Extract the major version number from the allowed kernel version. 146 | ALLOWED_KERNEL_MINOR_VERSION=$(echo ${ALLOWED_KERNEL_VERSION} | cut --delimiter="." --fields=2) 147 | # Extract the minor version number from the allowed kernel version. 148 | if [ "${CURRENT_KERNEL_MAJOR_VERSION}" -lt "${ALLOWED_KERNEL_MAJOR_VERSION}" ]; then 149 | # If the current major version is less than the allowed major version, show an error message and exit. 150 | echo "Error: Your current kernel version ${CURRENT_KERNEL_VERSION} is not supported. Please update to version ${ALLOWED_KERNEL_VERSION} or later." 151 | exit 152 | fi 153 | if [ "${CURRENT_KERNEL_MAJOR_VERSION}" == "${ALLOWED_KERNEL_MAJOR_VERSION}" ]; then 154 | # If the current major version is equal to the allowed major version, check the minor version. 155 | if [ "${CURRENT_KERNEL_MINOR_VERSION}" -lt "${ALLOWED_KERNEL_MINOR_VERSION}" ]; then 156 | # If the current minor version is less than the allowed minor version, show an error message and exit. 157 | echo "Error: Your current kernel version ${CURRENT_KERNEL_VERSION} is not supported. Please update to version ${ALLOWED_KERNEL_VERSION} or later." 158 | exit 159 | fi 160 | fi 161 | } 162 | 163 | # Call the kernel-check function to verify the kernel version. 164 | kernel-check 165 | 166 | # The following function checks if the current init system is one of the allowed options. 167 | function check-current-init-system() { 168 | # This function checks if the current init system is systemd or sysvinit. 169 | # If it is neither, the script exits. 170 | CURRENT_INIT_SYSTEM=$(ps --no-headers -o comm 1) 171 | # This line retrieves the current init system by checking the process name of PID 1. 172 | case ${CURRENT_INIT_SYSTEM} in 173 | # The case statement checks if the retrieved init system is one of the allowed options. 174 | *"systemd"* | *"init"* | *"bash"* | *"sh"*) 175 | # If the init system is systemd or sysvinit (init), continue with the script. 176 | ;; 177 | *) 178 | # If the init system is not one of the allowed options, display an error message and exit. 179 | echo "Error: The ${CURRENT_INIT_SYSTEM} initialization system is currently not supported. Please stay tuned for future updates." 180 | exit 181 | ;; 182 | esac 183 | } 184 | 185 | # The check-current-init-system function is being called. 186 | 187 | check-current-init-system 188 | # Calls the check-current-init-system function. 189 | 190 | # The following function checks if there's enough disk space to proceed with the installation. 191 | function check-disk-space() { 192 | # This function checks if there is more than 1 GB of free space on the drive. 193 | FREE_SPACE_ON_DRIVE_IN_MB=$(df -m / | tr --squeeze-repeats " " | tail -n1 | cut --delimiter=" " --fields=4) 194 | # This line calculates the available free space on the root partition in MB. 195 | if [ "${FREE_SPACE_ON_DRIVE_IN_MB}" -le 1024 ]; then 196 | # If the available free space is less than or equal to 1024 MB (1 GB), display an error message and exit. 197 | echo "Error: You need more than 1 GB of free space to install everything. Please free up some space and try again." 198 | exit 199 | fi 200 | } 201 | 202 | # The check-disk-space function is being called. 203 | 204 | check-disk-space 205 | # Calls the check-disk-space function. 206 | 207 | # Global variables 208 | # Assigns the path of the current script to a variable 209 | CURRENT_FILE_PATH=$(realpath "${0}") 210 | # Assigns the WireGuard website URL to a variable 211 | WIREGUARD_WEBSITE_URL="https://www.wireguard.com" 212 | # Assigns a path for WireGuard 213 | WIREGUARD_PATH="/etc/wireguard" 214 | # Assigns a path for WireGuard clients 215 | WIREGUARD_CLIENT_PATH="${WIREGUARD_PATH}/clients" 216 | # Assigns a public network interface name for WireGuard 217 | WIREGUARD_PUB_NIC="wg0" 218 | # Assigns a path for the WireGuard configuration file 219 | WIREGUARD_CONFIG="${WIREGUARD_PATH}/${WIREGUARD_PUB_NIC}.conf" 220 | # Assigns a path for the WireGuard additional peer configuration file 221 | WIREGUARD_ADD_PEER_CONFIG="${WIREGUARD_PATH}/${WIREGUARD_PUB_NIC}-add-peer.conf" 222 | # Assigns a path for system backups 223 | SYSTEM_BACKUP_PATH="/var/backups" 224 | # Assigns a path for the WireGuard configuration backup file 225 | WIREGUARD_CONFIG_BACKUP="${SYSTEM_BACKUP_PATH}/wireguard-manager.zip" 226 | # Assigns a path for the WireGuard backup password file 227 | WIREGUARD_BACKUP_PASSWORD_PATH="${HOME}/.wireguard-manager" 228 | # Assigns a path for the DNS resolver configuration file 229 | RESOLV_CONFIG="/etc/resolv.conf" 230 | # Assigns a path for the old DNS resolver configuration file 231 | RESOLV_CONFIG_OLD="${RESOLV_CONFIG}.old" 232 | # Assigns a path for Unbound DNS resolver 233 | UNBOUND_ROOT="/etc/unbound" 234 | # Assigns a path for the WireGuard Manager script 235 | UNBOUND_MANAGER="${UNBOUND_ROOT}/wireguard-manager" 236 | # Assigns a path for the Unbound configuration file 237 | UNBOUND_CONFIG="${UNBOUND_ROOT}/unbound.conf" 238 | # Assigns a path for the Unbound root hints file 239 | UNBOUND_ROOT_HINTS="${UNBOUND_ROOT}/root.hints" 240 | # Assigns a path for the Unbound anchor file 241 | UNBOUND_ANCHOR="/var/lib/unbound/root.key" 242 | if { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 243 | UNBOUND_ANCHOR="${UNBOUND_ROOT}/root.key" 244 | fi 245 | # Assigns a path for the Unbound configuration directory 246 | UNBOUND_CONFIG_DIRECTORY="${UNBOUND_ROOT}/unbound.conf.d" 247 | # Assigns a path for the Unbound hosts configuration file 248 | UNBOUND_CONFIG_HOST="${UNBOUND_CONFIG_DIRECTORY}/hosts.conf" 249 | case $(shuf --input-range=1-5 --head-count=1) in 250 | 1) 251 | UNBOUND_ROOT_SERVER_CONFIG_URL="https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/assets/named.cache" 252 | ;; 253 | 2) 254 | UNBOUND_ROOT_SERVER_CONFIG_URL="https://cdn.statically.io/gh/complexorganizations/wireguard-manager/main/assets/named.cache" 255 | ;; 256 | 3) 257 | UNBOUND_ROOT_SERVER_CONFIG_URL="https://cdn.jsdelivr.net/gh/complexorganizations/wireguard-manager/assets/named.cache" 258 | ;; 259 | 4) 260 | UNBOUND_ROOT_SERVER_CONFIG_URL="https://www.internic.net/domain/named.cache" 261 | ;; 262 | 5) 263 | UNBOUND_ROOT_SERVER_CONFIG_URL="https://gitlab.com/complex-organizations/wireguard-manager/-/raw/main/assets/named.cache" 264 | ;; 265 | esac 266 | case $(shuf --input-range=1-5 --head-count=1) in 267 | 1) 268 | UNBOUND_CONFIG_HOST_URL="https://raw.githubusercontent.com/complexorganizations/content-blocker/main/assets/hosts" 269 | ;; 270 | 2) 271 | UNBOUND_CONFIG_HOST_URL="https://cdn.statically.io/gh/complexorganizations/content-blocker/main/assets/hosts" 272 | ;; 273 | 3) 274 | UNBOUND_CONFIG_HOST_URL="https://cdn.jsdelivr.net/gh/complexorganizations/content-blocker/assets/hosts" 275 | ;; 276 | 4) 277 | UNBOUND_CONFIG_HOST_URL="https://combinatronics.io/complexorganizations/content-blocker/main/assets/hosts" 278 | ;; 279 | 5) 280 | UNBOUND_CONFIG_HOST_URL="https://gitlab.com/complex-organizations/wireguard-manager/-/raw/main/assets/hosts" 281 | ;; 282 | esac 283 | case $(shuf --input-range=1-5 --head-count=1) in 284 | 1) 285 | WIREGUARD_MANAGER_UPDATE="https://raw.githubusercontent.com/complexorganizations/wireguard-manager/main/wireguard-manager.sh" 286 | ;; 287 | 2) 288 | WIREGUARD_MANAGER_UPDATE="https://cdn.statically.io/gh/complexorganizations/wireguard-manager/main/wireguard-manager.sh" 289 | ;; 290 | 3) 291 | WIREGUARD_MANAGER_UPDATE="https://cdn.jsdelivr.net/gh/complexorganizations/wireguard-manager/wireguard-manager.sh" 292 | ;; 293 | 4) 294 | WIREGUARD_MANAGER_UPDATE="https://combinatronics.io/complexorganizations/wireguard-manager/main/wireguard-manager.sh" 295 | ;; 296 | 5) 297 | WIREGUARD_MANAGER_UPDATE="https://gitlab.com/complex-organizations/wireguard-manager/-/raw/main/wireguard-manager.sh" 298 | ;; 299 | esac 300 | # Check if the CURRENT_DISTRO variable matches any of the following distros: 301 | # fedora, centos, rhel, almalinux, or rocky 302 | if { [ "${CURRENT_DISTRO}" == "fedora" ] || [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "rhel" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 303 | # If the condition is true, set the SYSTEM_CRON_NAME variable to "crond" 304 | SYSTEM_CRON_NAME="crond" 305 | # If the CURRENT_DISTRO variable matches any of the following distros: 306 | # arch, archarm, or manjaro 307 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 308 | # If the condition is true, set the SYSTEM_CRON_NAME variable to "cronie" 309 | SYSTEM_CRON_NAME="cronie" 310 | else 311 | # If none of the above conditions are met, set the SYSTEM_CRON_NAME variable to "cron" 312 | SYSTEM_CRON_NAME="cron" 313 | fi 314 | 315 | # This is a Bash function named "get-network-information" that retrieves network information. 316 | function get-network-information() { 317 | # This variable will store the IPv4 address of the default network interface by querying the "ipengine" API using "curl" command and extracting it using "jq" command. 318 | DEFAULT_INTERFACE_IPV4="$(curl --ipv4 --connect-timeout 5 --tlsv1.2 --silent 'https://checkip.amazonaws.com')" 319 | # If the IPv4 address is empty, try getting it from another API. 320 | if [ -z "${DEFAULT_INTERFACE_IPV4}" ]; then 321 | DEFAULT_INTERFACE_IPV4="$(curl --ipv4 --connect-timeout 5 --tlsv1.3 --silent 'https://icanhazip.com')" 322 | fi 323 | # This variable will store the IPv6 address of the default network interface by querying the "ipengine" API using "curl" command and extracting it using "jq" command. 324 | DEFAULT_INTERFACE_IPV6="$(curl --ipv6 --connect-timeout 5 --tlsv1.3 --silent 'https://ifconfig.co')" 325 | # If the IPv6 address is empty, try getting it from another API. 326 | if [ -z "${DEFAULT_INTERFACE_IPV6}" ]; then 327 | DEFAULT_INTERFACE_IPV6="$(curl --ipv6 --connect-timeout 5 --tlsv1.3 --silent 'https://icanhazip.com')" 328 | fi 329 | } 330 | 331 | # Usage Guide of the application 332 | function usage-guide() { 333 | echo "Usage: ./$(basename "${0}") " 334 | echo " --install Installs the WireGuard interface on your system" 335 | echo " --start Starts the WireGuard interface if it's not already running" 336 | echo " --stop Stops the WireGuard interface if it's currently running" 337 | echo " --restart Restarts the WireGuard interface" 338 | echo " --list Lists all the peers currently connected to the WireGuard interface" 339 | echo " --add Adds a new peer to the WireGuard interface" 340 | echo " --remove Removes a specified peer from the WireGuard interface" 341 | echo " --reinstall Reinstalls the WireGuard interface, keeping the current configuration" 342 | echo " --uninstall Uninstalls the WireGuard interface from your system" 343 | echo " --update Updates the WireGuard Manager to the latest version" 344 | echo " --ddns Updates the IP address of the WireGuard interface using Dynamic DNS" 345 | echo " --backup Creates a backup of your current WireGuard configuration" 346 | echo " --restore Restores the WireGuard configuration from a previous backup" 347 | echo " --purge Removes all peers from the WireGuard interface" 348 | echo " --help Displays this usage guide" 349 | } 350 | 351 | # Define a function that takes command line arguments as input 352 | function usage() { 353 | # Check if there are any command line arguments left 354 | while [ $# -ne 0 ]; do 355 | # Use a switch-case statement to check the value of the first argument 356 | case ${1} in 357 | --install) # If it's "--install", set the variable HEADLESS_INSTALL to "true" 358 | shift 359 | HEADLESS_INSTALL=${HEADLESS_INSTALL=true} 360 | ;; 361 | --start) # If it's "--start", set the variable WIREGUARD_OPTIONS to 2 362 | shift 363 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=2} 364 | ;; 365 | --stop) # If it's "--stop", set the variable WIREGUARD_OPTIONS to 3 366 | shift 367 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=3} 368 | ;; 369 | --restart) # If it's "--restart", set the variable WIREGUARD_OPTIONS to 4 370 | shift 371 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=4} 372 | ;; 373 | --list) # If it's "--list", set the variable WIREGUARD_OPTIONS to 1 374 | shift 375 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=1} 376 | ;; 377 | --add) # If it's "--add", set the variable WIREGUARD_OPTIONS to 5 378 | shift 379 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=5} 380 | ;; 381 | --remove) # If it's "--remove", set the variable WIREGUARD_OPTIONS to 6 382 | shift 383 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=6} 384 | ;; 385 | --reinstall) # If it's "--reinstall", set the variable WIREGUARD_OPTIONS to 7 386 | shift 387 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=7} 388 | ;; 389 | --uninstall) # If it's "--uninstall", set the variable WIREGUARD_OPTIONS to 8 390 | shift 391 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=8} 392 | ;; 393 | --update) # If it's "--update", set the variable WIREGUARD_OPTIONS to 9 394 | shift 395 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=9} 396 | ;; 397 | --backup) # If it's "--backup", set the variable WIREGUARD_OPTIONS to 10 398 | shift 399 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=10} 400 | ;; 401 | --restore) # If it's "--restore", set the variable WIREGUARD_OPTIONS to 11 402 | shift 403 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=11} 404 | ;; 405 | --ddns) # If it's "--ddns", set the variable WIREGUARD_OPTIONS to 12 406 | shift 407 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=12} 408 | ;; 409 | --purge) # If it's "--purge", set the variable WIREGUARD_OPTIONS to 14 410 | shift 411 | WIREGUARD_OPTIONS=${WIREGUARD_OPTIONS=14} 412 | ;; 413 | --help) # If it's "--help", call the function usage-guide 414 | shift 415 | usage-guide 416 | ;; 417 | *) # If it's anything else, print an error message and call the function usage-guide, then exit 418 | echo "Invalid argument: ${1}" 419 | usage-guide 420 | exit 421 | ;; 422 | esac 423 | done 424 | } 425 | 426 | # Call the function usage with all the command line arguments 427 | usage "$@" 428 | 429 | # The function defines default values for configuration variables when installing WireGuard in headless mode. 430 | # These variables include private subnet settings, server host settings, NAT choice, MTU choice, client allowed IP settings, automatic updates, automatic backup, DNS provider settings, content blocker settings, client name, and automatic config remover. 431 | function headless-install() { 432 | # If headless installation is specified, set default values for configuration variables. 433 | if [ "${HEADLESS_INSTALL}" == true ]; then 434 | PRIVATE_SUBNET_V4_SETTINGS=${PRIVATE_SUBNET_V4_SETTINGS=1} # Default to 1 if not specified 435 | PRIVATE_SUBNET_V6_SETTINGS=${PRIVATE_SUBNET_V6_SETTINGS=1} # Default to 1 if not specified 436 | SERVER_HOST_V4_SETTINGS=${SERVER_HOST_V4_SETTINGS=1} # Default to 1 if not specified 437 | SERVER_HOST_V6_SETTINGS=${SERVER_HOST_V6_SETTINGS=1} # Default to 1 if not specified 438 | SERVER_PUB_NIC_SETTINGS=${SERVER_PUB_NIC_SETTINGS=1} # Default to 1 if not specified 439 | SERVER_PORT_SETTINGS=${SERVER_PORT_SETTINGS=1} # Default to 1 if not specified 440 | NAT_CHOICE_SETTINGS=${NAT_CHOICE_SETTINGS=1} # Default to 1 if not specified 441 | MTU_CHOICE_SETTINGS=${MTU_CHOICE_SETTINGS=1} # Default to 1 if not specified 442 | SERVER_HOST_SETTINGS=${SERVER_HOST_SETTINGS=1} # Default to 1 if not specified 443 | CLIENT_ALLOWED_IP_SETTINGS=${CLIENT_ALLOWED_IP_SETTINGS=1} # Default to 1 if not specified 444 | AUTOMATIC_UPDATES_SETTINGS=${AUTOMATIC_UPDATES_SETTINGS=1} # Default to 1 if not specified 445 | AUTOMATIC_BACKUP_SETTINGS=${AUTOMATIC_BACKUP_SETTINGS=1} # Default to 1 if not specified 446 | DNS_PROVIDER_SETTINGS=${DNS_PROVIDER_SETTINGS=1} # Default to 1 if not specified 447 | CONTENT_BLOCKER_SETTINGS=${CONTENT_BLOCKER_SETTINGS=1} # Default to 1 if not specified 448 | CLIENT_NAME=${CLIENT_NAME=$(openssl rand -hex 25)} # Generate a random client name if not specified 449 | AUTOMATIC_CONFIG_REMOVER=${AUTOMATIC_CONFIG_REMOVER=1} # Default to 1 if not specified 450 | fi 451 | } 452 | 453 | # Call the headless-install function to set default values for configuration variables in headless mode. 454 | headless-install 455 | 456 | # Set up the wireguard, if config it isn't already there. 457 | if [ ! -f "${WIREGUARD_CONFIG}" ]; then 458 | 459 | # Define a function to set a custom IPv4 subnet 460 | function set-ipv4-subnet() { 461 | # Prompt the user for the desired IPv4 subnet 462 | echo "Please specify the IPv4 subnet you want to use for the WireGuard interface. This should be a private subnet that is not in use elsewhere on your network. For example, you might choose '10.0.0.0/24' if it's not already in use." 463 | echo " 1) 10.0.0.0/8 (Recommended)" 464 | echo " 2) Custom (Advanced)" 465 | # Keep prompting the user until they enter a valid subnet choice 466 | until [[ "${PRIVATE_SUBNET_V4_SETTINGS}" =~ ^[1-2]$ ]]; do 467 | read -rp "Subnet Choice [1-2]:" -e -i 1 PRIVATE_SUBNET_V4_SETTINGS 468 | done 469 | # Based on the user's choice, set the private IPv4 subnet 470 | case ${PRIVATE_SUBNET_V4_SETTINGS} in 471 | 1) 472 | PRIVATE_SUBNET_V4="10.0.0.0/8" # Set a default IPv4 subnet 473 | ;; 474 | 2) 475 | read -rp "Custom IPv4 Subnet:" PRIVATE_SUBNET_V4 # Prompt user for custom subnet 476 | if [ -z "${PRIVATE_SUBNET_V4}" ]; then # If the user did not enter a subnet, set default 477 | PRIVATE_SUBNET_V4="10.0.0.0/8" 478 | fi 479 | ;; 480 | esac 481 | } 482 | 483 | # Call the function to set the custom IPv4 subnet 484 | set-ipv4-subnet 485 | 486 | # Define a function to set a custom IPv6 subnet 487 | function set-ipv6-subnet() { 488 | # Ask the user which IPv6 subnet they want to use 489 | echo "Please specify the IPv6 subnet you want to use for the WireGuard interface. This should be a private subnet that is not in use elsewhere on your network. For example, you might choose 'fd00::/64' if it's not already in use." 490 | echo " 1) fd00:00:00::0/8 (Recommended)" 491 | echo " 2) Custom (Advanced)" 492 | # Use a loop to ensure the user inputs a valid option 493 | until [[ "${PRIVATE_SUBNET_V6_SETTINGS}" =~ ^[1-2]$ ]]; do 494 | read -rp "Please choose the IPv6 subnet for your WireGuard interface [Option 1-2]: " -e -i 1 PRIVATE_SUBNET_V6_SETTINGS 495 | done 496 | # Use a case statement to set the IPv6 subnet based on the user's choice 497 | case ${PRIVATE_SUBNET_V6_SETTINGS} in 498 | 1) 499 | # Use the recommended IPv6 subnet if the user chooses option 1 500 | PRIVATE_SUBNET_V6="fd00:00:00::0/8" 501 | ;; 502 | 2) 503 | # Ask the user for a custom IPv6 subnet if they choose option 2 504 | read -rp "Please enter a custom IPv6 subnet for your WireGuard interface: " PRIVATE_SUBNET_V6 505 | # If the user does not input a subnet, use the recommended one 506 | if [ -z "${PRIVATE_SUBNET_V6}" ]; then 507 | PRIVATE_SUBNET_V6="fd00:00:00::0/8" 508 | fi 509 | ;; 510 | esac 511 | } 512 | 513 | # Call the set-ipv6-subnet function to set the custom IPv6 subnet 514 | set-ipv6-subnet 515 | 516 | # Define the private subnet mask for the IPv4 network used by the WireGuard interface 517 | PRIVATE_SUBNET_MASK_V4=$(echo "${PRIVATE_SUBNET_V4}" | cut --delimiter="/" --fields=2) # Get the subnet mask of IPv4 518 | # Define the IPv4 gateway for the WireGuard interface 519 | GATEWAY_ADDRESS_V4=$(echo "${PRIVATE_SUBNET_V4}" | cut --delimiter="." --fields=1-3).1 # Get the gateway address of IPv4 520 | # Define the private subnet mask for the IPv6 network used by the WireGuard interface 521 | PRIVATE_SUBNET_MASK_V6=$(echo "${PRIVATE_SUBNET_V6}" | cut --delimiter="/" --fields=2) # Get the subnet mask of IPv6 522 | # Define the IPv6 gateway for the WireGuard interface 523 | GATEWAY_ADDRESS_V6=$(echo "${PRIVATE_SUBNET_V6}" | cut --delimiter=":" --fields=1-3)::1 # Get the gateway address of IPv6 524 | # Retrieve the networking configuration details 525 | get-network-information 526 | # Call a function to get the networking data 527 | 528 | # Define a function to retrieve the IPv4 address of the WireGuard interface 529 | function test-connectivity-v4() { 530 | # Prompt the user to choose the method for detecting the IPv4 address 531 | echo "How would you like to detect IPv4?" 532 | echo " 1) Curl (Recommended)" 533 | echo " 2) Custom (Advanced)" 534 | # Loop until the user provides a valid input 535 | until [[ "${SERVER_HOST_V4_SETTINGS}" =~ ^[1-2]$ ]]; do 536 | read -rp "IPv4 Choice [1-2]:" -e -i 1 SERVER_HOST_V4_SETTINGS 537 | done 538 | # Choose the method for detecting the IPv4 address based on the user's input 539 | case ${SERVER_HOST_V4_SETTINGS} in 540 | 1) 541 | SERVER_HOST_V4=${DEFAULT_INTERFACE_IPV4} # Use the default IPv4 address 542 | ;; 543 | 2) 544 | # Prompt the user to enter a custom IPv4 address 545 | read -rp "Custom IPv4:" SERVER_HOST_V4 546 | # If the user doesn't provide an input, use the default IPv4 address 547 | if [ -z "${SERVER_HOST_V4}" ]; then 548 | SERVER_HOST_V4=${DEFAULT_INTERFACE_IPV4} 549 | fi 550 | ;; 551 | esac 552 | } 553 | 554 | # Call the function to retrieve the IPv4 address 555 | test-connectivity-v4 556 | # Invoke the function to get the IPv4 address 557 | 558 | # Define a function to retrieve the IPv6 address of the WireGuard interface 559 | function test-connectivity-v6() { 560 | # Prompt the user to choose the method for detecting the IPv6 address 561 | echo "How would you like to detect IPv6?" 562 | echo " 1) Curl (Recommended)" 563 | echo " 2) Custom (Advanced)" 564 | # Loop until the user provides a valid input 565 | until [[ "${SERVER_HOST_V6_SETTINGS}" =~ ^[1-2]$ ]]; do 566 | read -rp "IPv6 Choice [1-2]:" -e -i 1 SERVER_HOST_V6_SETTINGS 567 | done 568 | # Choose the method for detecting the IPv6 address based on the user's input 569 | case ${SERVER_HOST_V6_SETTINGS} in 570 | 1) 571 | SERVER_HOST_V6=${DEFAULT_INTERFACE_IPV6} # Use the default IPv6 address 572 | ;; 573 | 2) 574 | # Prompt the user to enter a custom IPv6 address 575 | read -rp "Custom IPv6:" SERVER_HOST_V6 576 | # If the user doesn't provide an input, use the default IPv6 address 577 | if [ -z "${SERVER_HOST_V6}" ]; then 578 | SERVER_HOST_V6=${DEFAULT_INTERFACE_IPV6} 579 | fi 580 | ;; 581 | esac 582 | } 583 | 584 | # Call the function to retrieve the IPv6 address 585 | test-connectivity-v6 586 | 587 | # Define a function to identify the public Network Interface Card (NIC). 588 | function server-pub-nic() { 589 | # Prompt the user to select the method for identifying the NIC. 590 | echo "How would you like to identify the Network Interface Card (NIC)?" 591 | echo " 1) IP Route (Recommended)" 592 | echo " 2) Custom Input (Advanced)" 593 | # Loop until the user provides a valid input (either 1 or 2). 594 | until [[ "${SERVER_PUB_NIC_SETTINGS}" =~ ^[1-2]$ ]]; do 595 | read -rp "NIC Choice [1-2]:" -e -i 1 SERVER_PUB_NIC_SETTINGS 596 | done 597 | # Execute a case statement based on the user's choice. 598 | case ${SERVER_PUB_NIC_SETTINGS} in 599 | 1) 600 | # Use the IP route command to automatically identify the NIC. 601 | SERVER_PUB_NIC="$(ip route | grep default | head --lines=1 | cut --delimiter=" " --fields=5)" 602 | # If no NIC is found, exit the script with an error message. 603 | if [ -z "${SERVER_PUB_NIC}" ]; then 604 | echo "Error: Unable to identify your server's public network interface." 605 | exit 606 | fi 607 | ;; 608 | 2) 609 | # Prompt the user to manually input the NIC. 610 | read -rp "Custom NIC:" SERVER_PUB_NIC 611 | # If the user doesn't provide an input, use the IP route command to identify the NIC. 612 | if [ -z "${SERVER_PUB_NIC}" ]; then 613 | SERVER_PUB_NIC="$(ip route | grep default | head --lines=1 | cut --delimiter=" " --fields=5)" 614 | fi 615 | ;; 616 | esac 617 | } 618 | 619 | # Call the function to identify the public NIC. 620 | server-pub-nic 621 | 622 | # Define a function to configure the WireGuard server's listening port 623 | function set-port() { 624 | # Prompt the user to specify the port for the WireGuard server 625 | echo "What port do you want WireGuard server to listen to?" 626 | # Provide the user with options for setting the port 627 | echo " 1) 51820 (Recommended)" 628 | echo " 2) Custom (Advanced)" 629 | # Continue prompting the user until a valid option (1 or 2) is selected 630 | until [[ "${SERVER_PORT_SETTINGS}" =~ ^[1-2]$ ]]; do 631 | # Ask the user for their port choice, with 1 as the default option 632 | read -rp "Port Choice [1-2]:" -e -i 1 SERVER_PORT_SETTINGS 633 | done 634 | # Set the SERVER_PORT variable based on the user's choice 635 | case ${SERVER_PORT_SETTINGS} in 636 | 1) 637 | SERVER_PORT="51820" 638 | # If the chosen port is already in use, display an error message and exit the script 639 | if [ "$(lsof -i UDP:"${SERVER_PORT}")" ]; then 640 | echo "Error: Please use a different port because ${SERVER_PORT} is already in use." 641 | exit 642 | fi 643 | ;; 644 | 2) 645 | # Continue prompting the user until a valid custom port number (between 1 and 65535) is entered 646 | until [[ "${SERVER_PORT}" =~ ^[0-9]+$ ]] && [ "${SERVER_PORT}" -ge 1 ] && [ "${SERVER_PORT}" -le 65535 ]; do 647 | read -rp "Custom port [1-65535]:" SERVER_PORT 648 | done 649 | # If no custom port is entered, set the SERVER_PORT variable to the default of 51820 650 | if [ -z "${SERVER_PORT}" ]; then 651 | SERVER_PORT="51820" 652 | fi 653 | # If the chosen port is already in use, display an error message and exit the script 654 | if [ "$(lsof -i UDP:"${SERVER_PORT}")" ]; then 655 | echo "Error: The port ${SERVER_PORT} is already used by a different application, please use a different port." 656 | exit 657 | fi 658 | ;; 659 | esac 660 | } 661 | 662 | # Invoke the set-port function to configure the WireGuard server's listening port 663 | set-port 664 | 665 | # Define a function to set the NAT keepalive interval. 666 | function nat-keepalive() { 667 | # Prompt the user to specify the NAT keepalive interval. 668 | echo "What do you want your NAT keepalive interval to be?" 669 | # Provide the user with options for setting the interval. 670 | echo " 1) 25 seconds (Default)" 671 | echo " 2) Custom (Advanced)" 672 | # Continue prompting the user until a valid option (1 or 2) is selected. 673 | until [[ "${NAT_CHOICE_SETTINGS}" =~ ^[1-2]$ ]]; do 674 | # Ask the user for their interval choice, with 1 as the default option. 675 | read -rp "Keepalive Choice [1-2]:" -e -i 1 NAT_CHOICE_SETTINGS 676 | done 677 | # Set the NAT_CHOICE variable based on the user's choice. 678 | case ${NAT_CHOICE_SETTINGS} in 679 | 1) 680 | # If the user chose the default option, set the NAT_CHOICE to 25 seconds. 681 | NAT_CHOICE="25" 682 | ;; 683 | 2) 684 | # If the user chose the custom option, prompt them to enter a custom interval. 685 | until [[ "${NAT_CHOICE}" =~ ^[0-9]+$ ]] && [ "${NAT_CHOICE}" -ge 1 ] && [ "${NAT_CHOICE}" -le 65535 ]; do 686 | read -rp "Custom NAT [1-65535]:" NAT_CHOICE 687 | done 688 | # If no custom interval is entered, set the NAT_CHOICE variable to the default of 25 seconds. 689 | if [ -z "${NAT_CHOICE}" ]; then 690 | NAT_CHOICE="25" 691 | fi 692 | ;; 693 | esac 694 | } 695 | # Invoke the nat-keepalive function to set the NAT keepalive interval. 696 | nat-keepalive 697 | 698 | # Define a function to configure the Maximum Transmission Unit (MTU) settings. 699 | function mtu-set() { 700 | # Ask the user to specify the MTU settings. 701 | echo "What MTU do you want to use?" 702 | # Provide the user with options for setting the MTU. 703 | echo " 1) 1420 for Interface, 1280 for Peer (Recommended)" 704 | echo " 2) Custom (Advanced)" 705 | # Continue prompting the user until a valid option (1 or 2) is selected. 706 | until [[ "${MTU_CHOICE_SETTINGS}" =~ ^[1-2]$ ]]; do 707 | # Ask the user for their MTU choice, with 1 as the default option. 708 | read -rp "MTU Choice [1-2]:" -e -i 1 MTU_CHOICE_SETTINGS 709 | done 710 | # Set the MTU variables based on the user's choice. 711 | case ${MTU_CHOICE_SETTINGS} in 712 | 1) 713 | # If the user chose the default option, set the Interface MTU to 1420 and Peer MTU to 1280. 714 | INTERFACE_MTU_CHOICE="1420" 715 | PEER_MTU_CHOICE="1280" 716 | ;; 717 | 2) 718 | # If the user chose the custom option, prompt them to enter a custom MTU for Interface and Peer. 719 | until [[ "${INTERFACE_MTU_CHOICE}" =~ ^[0-9]+$ ]] && [ "${INTERFACE_MTU_CHOICE}" -ge 1 ] && [ "${INTERFACE_MTU_CHOICE}" -le 65535 ]; do 720 | read -rp "Custom Interface MTU [1-65535]:" INTERFACE_MTU_CHOICE 721 | done 722 | # If no custom Interface MTU is entered, set the INTERFACE_MTU_CHOICE variable to the default of 1420. 723 | if [ -z "${INTERFACE_MTU_CHOICE}" ]; then 724 | INTERFACE_MTU_CHOICE="1420" 725 | fi 726 | until [[ "${PEER_MTU_CHOICE}" =~ ^[0-9]+$ ]] && [ "${PEER_MTU_CHOICE}" -ge 1 ] && [ "${PEER_MTU_CHOICE}" -le 65535 ]; do 727 | read -rp "Custom Peer MTU [1-65535]:" PEER_MTU_CHOICE 728 | done 729 | # If no custom Peer MTU is entered, set the PEER_MTU_CHOICE variable to the default of 1280. 730 | if [ -z "${PEER_MTU_CHOICE}" ]; then 731 | PEER_MTU_CHOICE="1280" 732 | fi 733 | ;; 734 | esac 735 | } 736 | 737 | # Invoke the mtu-set function to configure the MTU settings. 738 | mtu-set 739 | 740 | # Define a function to select the IP version for the WireGuard server. 741 | function ipvx-select() { 742 | # Ask the user to specify the IP version to use for connecting to the WireGuard server. 743 | echo "Which IP version do you want to use for the WireGuard server?" 744 | # Provide the user with options for setting the IP version. 745 | echo " 1) IPv4 (Recommended)" 746 | echo " 2) IPv6" 747 | # Continue prompting the user until a valid option (1 or 2) is selected. 748 | until [[ "${SERVER_HOST_SETTINGS}" =~ ^[1-2]$ ]]; do 749 | # Ask the user for their IP version choice, with 1 as the default option. 750 | read -rp "IP Version Choice [1-2]:" -e -i 1 SERVER_HOST_SETTINGS 751 | done 752 | # Set the SERVER_HOST variable based on the user's choice. 753 | case ${SERVER_HOST_SETTINGS} in 754 | 1) 755 | # If the user chose IPv4 and a default IPv4 interface is available, use it. 756 | if [ -n "${DEFAULT_INTERFACE_IPV4}" ]; then 757 | SERVER_HOST="${DEFAULT_INTERFACE_IPV4}" 758 | else 759 | # If no default IPv4 interface is available, use the default IPv6 interface. 760 | SERVER_HOST="[${DEFAULT_INTERFACE_IPV6}]" 761 | fi 762 | ;; 763 | 2) 764 | # If the user chose IPv6 and a default IPv6 interface is available, use it. 765 | if [ -n "${DEFAULT_INTERFACE_IPV6}" ]; then 766 | SERVER_HOST="[${DEFAULT_INTERFACE_IPV6}]" 767 | else 768 | # If no default IPv6 interface is available, use the default IPv4 interface. 769 | SERVER_HOST="${DEFAULT_INTERFACE_IPV4}" 770 | fi 771 | ;; 772 | esac 773 | } 774 | 775 | # Invoke the ipvx-select function to select the IP version for the WireGuard server. 776 | ipvx-select 777 | 778 | # Define a function to configure the type of traffic the client is allowed to forward through WireGuard. 779 | function client-allowed-ip() { 780 | # Ask the user to specify the type of traffic to be forwarded. 781 | echo "What type of traffic do you want the client to forward through WireGuard?" 782 | # Provide the user with options for setting the traffic type. 783 | echo " 1) All Traffic (Recommended)" 784 | echo " 2) Custom Traffic (Advanced)" 785 | # Continue prompting the user until a valid option (1 or 2) is selected. 786 | until [[ "${CLIENT_ALLOWED_IP_SETTINGS}" =~ ^[1-2]$ ]]; do 787 | # Ask the user for their traffic type choice, with 1 as the default option. 788 | read -rp "Traffic Type Choice [1-2]:" -e -i 1 CLIENT_ALLOWED_IP_SETTINGS 789 | done 790 | # Set the CLIENT_ALLOWED_IP variable based on the user's choice. 791 | case ${CLIENT_ALLOWED_IP_SETTINGS} in 792 | 1) 793 | # If the user chose the default option, set the CLIENT_ALLOWED_IP to allow all traffic. 794 | CLIENT_ALLOWED_IP="0.0.0.0/0,::/0" 795 | ;; 796 | 2) 797 | # If the user chose the custom option, prompt them to enter a custom IP range. 798 | read -rp "Custom IP Range:" CLIENT_ALLOWED_IP 799 | # If no custom IP range is entered, set the CLIENT_ALLOWED_IP variable to allow all traffic. 800 | if [ -z "${CLIENT_ALLOWED_IP}" ]; then 801 | CLIENT_ALLOWED_IP="0.0.0.0/0,::/0" 802 | fi 803 | ;; 804 | esac 805 | } 806 | 807 | # Invoke the client-allowed-ip function to configure the type of traffic the client is allowed to forward. 808 | client-allowed-ip 809 | 810 | # Function to configure automatic updates 811 | function enable-automatic-updates() { 812 | # Prompt the user to decide if they want to enable automatic updates 813 | echo "Would you like to setup real-time updates?" 814 | # Option 1: Enable automatic updates 815 | echo " 1) Yes (Recommended)" 816 | # Option 2: Disable automatic updates 817 | echo " 2) No (Advanced)" 818 | # Loop until a valid choice (1 or 2) is made 819 | until [[ "${AUTOMATIC_UPDATES_SETTINGS}" =~ ^[1-2]$ ]]; do 820 | # Read user input for automatic updates setting 821 | read -rp "Automatic Updates [1-2]:" -e -i 1 AUTOMATIC_UPDATES_SETTINGS 822 | done 823 | # Evaluate user choice for automatic updates 824 | case ${AUTOMATIC_UPDATES_SETTINGS} in 825 | 1) 826 | # If user chose to enable automatic updates, set up a cron job 827 | crontab -l | { 828 | cat 829 | # Add a cron job to run the script with --update option every day at midnight 830 | echo "0 0 * * * ${CURRENT_FILE_PATH} --update" 831 | } | crontab - 832 | # Check the init system in use 833 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 834 | # If systemd is in use, enable and start the cron service 835 | systemctl enable --now ${SYSTEM_CRON_NAME} 836 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 837 | # If initd is in use, start the cron service 838 | service ${SYSTEM_CRON_NAME} start 839 | fi 840 | ;; 841 | 2) 842 | # If user chose to disable automatic updates, display a confirmation message 843 | echo "Real-time Updates Disabled" 844 | ;; 845 | esac 846 | } 847 | 848 | # Invoke the function to configure automatic updates 849 | enable-automatic-updates 850 | 851 | # Function to configure automatic backup 852 | function enable-automatic-backup() { 853 | # Prompt the user to decide if they want to enable automatic backup 854 | echo "Would you like to setup real-time backup?" 855 | # Option 1: Enable automatic backup 856 | echo " 1) Yes (Recommended)" 857 | # Option 2: Disable automatic backup 858 | echo " 2) No (Advanced)" 859 | # Loop until a valid choice (1 or 2) is made 860 | until [[ "${AUTOMATIC_BACKUP_SETTINGS}" =~ ^[1-2]$ ]]; do 861 | # Read user input for automatic backup setting 862 | read -rp "Automatic Backup [1-2]:" -e -i 1 AUTOMATIC_BACKUP_SETTINGS 863 | done 864 | # Evaluate user choice for automatic backup 865 | case ${AUTOMATIC_BACKUP_SETTINGS} in 866 | 1) 867 | # If user chose to enable automatic backup, set up a cron job 868 | crontab -l | { 869 | cat 870 | # Add a cron job to run the script with --backup option every day at midnight 871 | echo "0 0 * * * ${CURRENT_FILE_PATH} --backup" 872 | } | crontab - 873 | # Check the init system in use 874 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 875 | # If systemd is in use, enable and start the cron service 876 | systemctl enable --now ${SYSTEM_CRON_NAME} 877 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 878 | # If initd is in use, start the cron service 879 | service ${SYSTEM_CRON_NAME} start 880 | fi 881 | ;; 882 | 2) 883 | # If user chose to disable automatic backup, display a confirmation message 884 | echo "Real-time Backup Disabled" 885 | ;; 886 | esac 887 | } 888 | 889 | # Invoke the function to configure automatic backup 890 | enable-automatic-backup 891 | 892 | # Function to prompt the user for their preferred DNS provider. 893 | function ask-install-dns() { 894 | # Display the DNS provider options to the user. 895 | echo "Which DNS provider would you like to use?" 896 | echo " 1) Unbound (Recommended)" 897 | echo " 2) Custom (Advanced)" 898 | # Continue prompting until the user enters a valid choice (1 or 2). 899 | until [[ "${DNS_PROVIDER_SETTINGS}" =~ ^[1-2]$ ]]; do 900 | # Read the user's DNS provider choice and store it in DNS_PROVIDER_SETTINGS. 901 | read -rp "DNS provider [1-2]:" -e -i 1 DNS_PROVIDER_SETTINGS 902 | done 903 | # Set variables based on the user's DNS provider choice. 904 | case ${DNS_PROVIDER_SETTINGS} in 905 | 1) 906 | # If the user chose Unbound, set INSTALL_UNBOUND to true. 907 | INSTALL_UNBOUND=true 908 | # Ask the user if they want to install a content-blocker. 909 | echo "Do you want to prevent advertisements, tracking, malware, and phishing using the content-blocker?" 910 | echo " 1) Yes (Recommended)" 911 | echo " 2) No" 912 | # Continue prompting until the user enters a valid choice (1 or 2). 913 | until [[ "${CONTENT_BLOCKER_SETTINGS}" =~ ^[1-2]$ ]]; do 914 | # Read the user's content blocker choice and store it in CONTENT_BLOCKER_SETTINGS. 915 | read -rp "Content Blocker Choice [1-2]:" -e -i 1 CONTENT_BLOCKER_SETTINGS 916 | done 917 | # Set INSTALL_BLOCK_LIST based on the user's content blocker choice. 918 | case ${CONTENT_BLOCKER_SETTINGS} in 919 | 1) 920 | # If the user chose to install the content blocker, set INSTALL_BLOCK_LIST to true. 921 | INSTALL_BLOCK_LIST=true 922 | ;; 923 | 2) 924 | # If the user chose not to install the content blocker, set INSTALL_BLOCK_LIST to false. 925 | INSTALL_BLOCK_LIST=false 926 | ;; 927 | esac 928 | ;; 929 | 2) 930 | # If the user chose to use a custom DNS provider, set CUSTOM_DNS to true. 931 | CUSTOM_DNS=true 932 | ;; 933 | esac 934 | } 935 | 936 | # Invoke the ask-install-dns function to begin the DNS provider selection process. 937 | ask-install-dns 938 | 939 | # Function to allow users to select a custom DNS provider. 940 | function custom-dns() { 941 | # If the custom DNS option is enabled, proceed with the DNS selection. 942 | if [ "${CUSTOM_DNS}" == true ]; then 943 | # Present the user with a list of DNS providers to choose from. 944 | echo "Select the DNS provider you wish to use with your WireGuard connection:" 945 | echo " 1) Cloudflare (Recommended)" 946 | echo " 2) AdGuard" 947 | echo " 3) NextDNS" 948 | echo " 4) OpenDNS" 949 | echo " 5) Google" 950 | echo " 6) Verisign" 951 | echo " 7) Quad9" 952 | echo " 8) FDN" 953 | echo " 9) Custom (Advanced)" 954 | # If Pi-Hole is installed, add it as an option. 955 | if [ -x "$(command -v pihole)" ]; then 956 | echo " 10) Pi-Hole (Advanced)" 957 | fi 958 | # Prompt the user to make a selection from the list of DNS providers. 959 | until [[ "${CLIENT_DNS_SETTINGS}" =~ ^[0-9]+$ ]] && [ "${CLIENT_DNS_SETTINGS}" -ge 1 ] && [ "${CLIENT_DNS_SETTINGS}" -le 10 ]; do 960 | read -rp "DNS [1-10]:" -e -i 1 CLIENT_DNS_SETTINGS 961 | done 962 | # Based on the user's selection, set the DNS addresses. 963 | case ${CLIENT_DNS_SETTINGS} in 964 | 1) 965 | # Set DNS addresses for Cloudflare. 966 | CLIENT_DNS="1.1.1.1,1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001" 967 | ;; 968 | 2) 969 | # Set DNS addresses for AdGuard. 970 | CLIENT_DNS="94.140.14.14,94.140.15.15,2a10:50c0::ad1:ff,2a10:50c0::ad2:ff" 971 | ;; 972 | 3) 973 | # Set DNS addresses for NextDNS. 974 | CLIENT_DNS="45.90.28.167,45.90.30.167,2a07:a8c0::12:cf53,2a07:a8c1::12:cf53" 975 | ;; 976 | 4) 977 | # Set DNS addresses for OpenDNS. 978 | CLIENT_DNS="208.67.222.222,208.67.220.220,2620:119:35::35,2620:119:53::53" 979 | ;; 980 | 5) 981 | # Set DNS addresses for Google. 982 | CLIENT_DNS="8.8.8.8,8.8.4.4,2001:4860:4860::8888,2001:4860:4860::8844" 983 | ;; 984 | 6) 985 | # Set DNS addresses for Verisign. 986 | CLIENT_DNS="64.6.64.6,64.6.65.6,2620:74:1b::1:1,2620:74:1c::2:2" 987 | ;; 988 | 7) 989 | # Set DNS addresses for Quad9. 990 | CLIENT_DNS="9.9.9.9,149.112.112.112,2620:fe::fe,2620:fe::9" 991 | ;; 992 | 8) 993 | # Set DNS addresses for FDN. 994 | CLIENT_DNS="80.67.169.40,80.67.169.12,2001:910:800::40,2001:910:800::12" 995 | ;; 996 | 9) 997 | # Prompt the user to enter a custom DNS address. 998 | read -rp "Custom DNS:" CLIENT_DNS 999 | # If the user doesn't provide a custom DNS, default to Google's DNS. 1000 | if [ -z "${CLIENT_DNS}" ]; then 1001 | CLIENT_DNS="8.8.8.8,8.8.4.4,2001:4860:4860::8888,2001:4860:4860::8844" 1002 | fi 1003 | ;; 1004 | 10) 1005 | # If Pi-Hole is installed, use its DNS. Otherwise, install Unbound and enable the block list. 1006 | if [ -x "$(command -v pihole)" ]; then 1007 | CLIENT_DNS="${GATEWAY_ADDRESS_V4},${GATEWAY_ADDRESS_V6}" 1008 | else 1009 | INSTALL_UNBOUND=true 1010 | INSTALL_BLOCK_LIST=true 1011 | fi 1012 | ;; 1013 | esac 1014 | fi 1015 | } 1016 | 1017 | # Invoke the custom-dns function to allow the user to select a DNS provider. 1018 | custom-dns 1019 | 1020 | # Function to prompt for the name of the first WireGuard peer. 1021 | function client-name() { 1022 | # If CLIENT_NAME variable is not set, prompt the user for input. 1023 | if [ -z "${CLIENT_NAME}" ]; then 1024 | # Display naming rules to the user. 1025 | echo "Please provide a name for the WireGuard Peer. The name should be a single word, without special characters or spaces." 1026 | # Read the user's input, offering a random string as the default name. 1027 | read -rp "Client name:" -e -i "$(openssl rand -hex 25)" CLIENT_NAME 1028 | fi 1029 | # If no name is provided by the user, assign a random string as the name. 1030 | if [ -z "${CLIENT_NAME}" ]; then 1031 | CLIENT_NAME="$(openssl rand -hex 25)" 1032 | fi 1033 | } 1034 | 1035 | # Invoke the function to prompt for the first WireGuard peer's name. 1036 | client-name 1037 | 1038 | # Function to set up automatic deletion of WireGuard peers. 1039 | function auto-remove-config() { 1040 | # Ask the user if they want to set an expiration date for the peer. 1041 | echo "Do you want to set an expiration date for the peer?" 1042 | echo " 1) Yes, expire after one year (Recommended)" 1043 | echo " 2) No, do not expire" 1044 | # Keep asking until the user enters 1 or 2. 1045 | until [[ "${AUTOMATIC_CONFIG_REMOVER}" =~ ^[1-2]$ ]]; do 1046 | read -rp "Choose an option for peer expiration [1-2]:" -e -i 1 AUTOMATIC_CONFIG_REMOVER 1047 | done 1048 | # Execute actions based on the user's choice. 1049 | case ${AUTOMATIC_CONFIG_REMOVER} in 1050 | 1) 1051 | # If the user chose to expire the peer, set the expiration flag to true. 1052 | AUTOMATIC_WIREGUARD_EXPIRATION=true 1053 | # Depending on the init system, enable and start the cron service. 1054 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1055 | systemctl enable --now ${SYSTEM_CRON_NAME} 1056 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1057 | service ${SYSTEM_CRON_NAME} start 1058 | fi 1059 | ;; 1060 | 2) 1061 | # If the user chose not to expire the peer, set the expiration flag to false. 1062 | AUTOMATIC_WIREGUARD_EXPIRATION=false 1063 | ;; 1064 | esac 1065 | } 1066 | 1067 | # Invoke the function to set up automatic deletion of WireGuard peers. 1068 | auto-remove-config 1069 | 1070 | # Function to verify kernel version and install necessary kernel headers. 1071 | function install-kernel-headers() { 1072 | # Define the minimum kernel version required and extract its major and minor version numbers. 1073 | MINIMUM_KERNEL_VERSION="5.6" 1074 | MINIMUM_KERNEL_MAJOR_VERSION=$(echo ${MINIMUM_KERNEL_VERSION} | cut --delimiter="." --fields=1) 1075 | MINIMUM_KERNEL_MINOR_VERSION=$(echo ${MINIMUM_KERNEL_VERSION} | cut --delimiter="." --fields=2) 1076 | # Check if the current kernel version is less than or equal to the minimum required version. 1077 | if [ "${CURRENT_KERNEL_MAJOR_VERSION}" -le "${MINIMUM_KERNEL_MAJOR_VERSION}" ]; then 1078 | INSTALL_LINUX_HEADERS=true 1079 | fi 1080 | # If the current kernel major version matches the minimum required major version, compare minor versions. 1081 | if [ "${CURRENT_KERNEL_MAJOR_VERSION}" == "${MINIMUM_KERNEL_MAJOR_VERSION}" ]; then 1082 | # If the current minor version is less than the required, set flag to install headers. 1083 | if [ "${CURRENT_KERNEL_MINOR_VERSION}" -lt "${MINIMUM_KERNEL_MINOR_VERSION}" ]; then 1084 | INSTALL_LINUX_HEADERS=true 1085 | fi 1086 | # If the current minor version is greater than or equal to the required, set flag to not install headers. 1087 | if [ "${CURRENT_KERNEL_MINOR_VERSION}" -ge "${MINIMUM_KERNEL_MINOR_VERSION}" ]; then 1088 | INSTALL_LINUX_HEADERS=false 1089 | fi 1090 | fi 1091 | # If the flag to install headers is set, install appropriate headers based on the Linux distribution. 1092 | if [ "${INSTALL_LINUX_HEADERS}" == true ]; then 1093 | if { [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ]; }; then 1094 | apt-get update 1095 | apt-get install linux-headers-"$(uname --kernel-release)" -y 1096 | elif [ "${CURRENT_DISTRO}" == "raspbian" ]; then 1097 | apt-get update 1098 | apt-get install raspberrypi-kernel-headers -y 1099 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 1100 | pacman -Su --noconfirm --needed linux-headers 1101 | elif { [ "${CURRENT_DISTRO}" == "fedora" ] || [ "${CURRENT_DISTRO}" == "ol" ]; }; then 1102 | yum check-update 1103 | yum install kernel-headers-"$(uname --kernel-release)" kernel-devel-"$(uname --kernel-release)" -y 1104 | elif { [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "rhel" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 1105 | yum check-update 1106 | yum install kernel-headers-"$(uname --kernel-release)" kernel-devel-"$(uname --kernel-release)" -y 1107 | fi 1108 | fi 1109 | } 1110 | 1111 | # Invoke the function to verify kernel version and install necessary kernel headers. 1112 | install-kernel-headers 1113 | 1114 | # Function to install either resolvconf or openresolv, depending on the distribution. 1115 | function install-resolvconf-or-openresolv() { 1116 | # Check if resolvconf is already installed on the system. 1117 | if [ ! -x "$(command -v resolvconf)" ]; then 1118 | # If resolvconf is not installed, install it for Ubuntu, Debian, Raspbian, Pop, Kali, Linux Mint, and Neon distributions. 1119 | if { [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "raspbian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ]; }; then 1120 | apt-get install resolvconf -y 1121 | # For CentOS, RHEL, AlmaLinux, and Rocky distributions, install openresolv. 1122 | elif { [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "rhel" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 1123 | # If the distribution is CentOS 7, enable the copr repository before installing openresolv. 1124 | if [ "${CURRENT_DISTRO}" == "centos" ] && [ "${CURRENT_DISTRO_MAJOR_VERSION}" == 7 ]; then 1125 | yum copr enable macieks/openresolv -y 1126 | fi 1127 | yum install openresolv -y 1128 | # For Fedora and Oracle Linux distributions, install openresolv. 1129 | elif { [ "${CURRENT_DISTRO}" == "fedora" ] || [ "${CURRENT_DISTRO}" == "ol" ]; }; then 1130 | yum install openresolv -y 1131 | # For Arch, Arch ARM, and Manjaro distributions, install resolvconf. 1132 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 1133 | pacman -Su --noconfirm --needed resolvconf 1134 | # For Alpine Linux, install resolvconf. 1135 | elif [ "${CURRENT_DISTRO}" == "alpine" ]; then 1136 | apk add resolvconf 1137 | # For FreeBSD, install resolvconf. 1138 | elif [ "${CURRENT_DISTRO}" == "freebsd" ]; then 1139 | pkg install resolvconf 1140 | fi 1141 | fi 1142 | } 1143 | 1144 | # Invoke the function to install either resolvconf or openresolv, depending on the distribution. 1145 | install-resolvconf-or-openresolv 1146 | 1147 | # Function to install the WireGuard server if it's not already installed. 1148 | function install-wireguard-server() { 1149 | # Verify if the WireGuard command (wg) is available on the system. 1150 | if [ ! -x "$(command -v wg)" ]; then 1151 | # For Debian-based distributions, update the package list and install WireGuard. 1152 | if { [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "raspbian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ]; }; then 1153 | apt-get update 1154 | apt-get install wireguard -y 1155 | # For Arch-based distributions, update the package list and install WireGuard tools. 1156 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 1157 | pacman -Su --noconfirm --needed wireguard-tools 1158 | elif [ "${CURRENT_DISTRO}" = "fedora" ]; then 1159 | dnf check-update 1160 | dnf copr enable jdoss/wireguard -y 1161 | dnf install wireguard-tools -y 1162 | # For CentOS, update the package list and install WireGuard tools and kernel module. 1163 | elif [ "${CURRENT_DISTRO}" == "centos" ]; then 1164 | yum check-update 1165 | yum install kmod-wireguard wireguard-tools -y 1166 | # For RHEL, install necessary repositories and then install WireGuard tools and kernel module. 1167 | elif [ "${CURRENT_DISTRO}" == "rhel" ]; then 1168 | yum check-update 1169 | yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-"${CURRENT_DISTRO_MAJOR_VERSION}".noarch.rpm https://www.elrepo.org/elrepo-release-"${CURRENT_DISTRO_MAJOR_VERSION}".el"${CURRENT_DISTRO_MAJOR_VERSION}".elrepo.noarch.rpm 1170 | yum check-update 1171 | yum install kmod-wireguard wireguard-tools -y 1172 | # For Alpine Linux, update the package list and install WireGuard tools. 1173 | elif [ "${CURRENT_DISTRO}" == "alpine" ]; then 1174 | apk update 1175 | apk add wireguard-tools 1176 | # For FreeBSD, update the package list and install WireGuard. 1177 | elif [ "${CURRENT_DISTRO}" == "freebsd" ]; then 1178 | pkg update 1179 | pkg install wireguard 1180 | # For AlmaLinux and Rocky, update the package list and install WireGuard tools and kernel module. 1181 | elif { [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 1182 | yum check-update 1183 | yum install kmod-wireguard wireguard-tools -y 1184 | # For Oracle Linux, configure necessary repositories and then install WireGuard tools. 1185 | elif [ "${CURRENT_DISTRO}" == "ol" ]; then 1186 | yum check-update 1187 | yum install oraclelinux-developer-release-el"${CURRENT_DISTRO_MAJOR_VERSION}" -y 1188 | yum config-manager --disable ol"${CURRENT_DISTRO_MAJOR_VERSION}"_developer 1189 | yum config-manager --enable ol"${CURRENT_DISTRO_MAJOR_VERSION}"_developer_UEKR6 1190 | yum config-manager --save --setopt=ol"${CURRENT_DISTRO_MAJOR_VERSION}"_developer_UEKR6.includepkgs='wireguard-tools*' 1191 | yum install wireguard-tools -y 1192 | fi 1193 | fi 1194 | } 1195 | 1196 | # Invoke the function to install the WireGuard server. 1197 | install-wireguard-server 1198 | 1199 | # Function to install Unbound, a DNS resolver, if required and not already installed. 1200 | function install-unbound() { 1201 | # If INSTALL_UNBOUND is true and Unbound is not installed, proceed with installation. 1202 | if [ "${INSTALL_UNBOUND}" == true ]; then 1203 | if [ ! -x "$(command -v unbound)" ]; then 1204 | # Installation commands for Unbound vary based on the Linux distribution. 1205 | # The following checks the distribution and installs Unbound accordingly. 1206 | # For Debian-based distributions: 1207 | if { [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "raspbian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ]; }; then 1208 | apt-get install unbound unbound-host unbound-anchor -y 1209 | # If the distribution is Ubuntu, disable systemd-resolved. 1210 | if [ "${CURRENT_DISTRO}" == "ubuntu" ]; then 1211 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1212 | systemctl disable --now systemd-resolved 1213 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1214 | service systemd-resolved stop 1215 | fi 1216 | fi 1217 | # For CentOS, RHEL, AlmaLinux, and Rocky: 1218 | elif { [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "rhel" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 1219 | yum install unbound unbound-host unbound-anchor -y 1220 | # For Fedora: 1221 | elif [ "${CURRENT_DISTRO}" == "fedora" ]; then 1222 | dnf install unbound unbound-host unbound-anchor -y 1223 | # For Arch-based distributions: 1224 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 1225 | pacman -Su --noconfirm --needed unbound 1226 | # For Alpine Linux: 1227 | elif [ "${CURRENT_DISTRO}" == "alpine" ]; then 1228 | apk add unbound unbound-host unbound-anchor 1229 | # For FreeBSD: 1230 | elif [ "${CURRENT_DISTRO}" == "freebsd" ]; then 1231 | pkg install unbound unbound-host unbound-anchor 1232 | # For Oracle Linux: 1233 | elif [ "${CURRENT_DISTRO}" == "ol" ]; then 1234 | yum install unbound unbound-host unbound-anchor -y 1235 | fi 1236 | fi 1237 | # Configure Unbound using anchor and root hints. 1238 | unbound-anchor -a ${UNBOUND_ANCHOR} 1239 | # Download root hints. 1240 | curl "${UNBOUND_ROOT_SERVER_CONFIG_URL}" --create-dirs -o ${UNBOUND_ROOT_HINTS} 1241 | # Configure Unbound settings. 1242 | # The settings are stored in a temporary variable and then written to the Unbound configuration file. 1243 | # If INSTALL_BLOCK_LIST is true, include a block list in the Unbound configuration. 1244 | # Configure Unbound settings. 1245 | UNBOUND_TEMP_INTERFACE_INFO="server: 1246 | \tnum-threads: $(nproc) 1247 | \tverbosity: 0 1248 | \troot-hints: ${UNBOUND_ROOT_HINTS} 1249 | \tauto-trust-anchor-file: ${UNBOUND_ANCHOR} 1250 | \tinterface: 0.0.0.0 1251 | \tinterface: ::0 1252 | \tport: 53 1253 | \tmax-udp-size: 3072 1254 | \taccess-control: 0.0.0.0/0\trefuse 1255 | \taccess-control: ::0\trefuse 1256 | \taccess-control: ${PRIVATE_SUBNET_V4}\tallow 1257 | \taccess-control: ${PRIVATE_SUBNET_V6}\tallow 1258 | \taccess-control: 127.0.0.1\tallow 1259 | \taccess-control: ::1\tallow 1260 | \tprivate-address: ${PRIVATE_SUBNET_V4} 1261 | \tprivate-address: ${PRIVATE_SUBNET_V6} 1262 | \tprivate-address: 10.0.0.0/8 1263 | \tprivate-address: 127.0.0.0/8 1264 | \tprivate-address: 169.254.0.0/16 1265 | \tprivate-address: 172.16.0.0/12 1266 | \tprivate-address: 192.168.0.0/16 1267 | \tprivate-address: ::ffff:0:0/96 1268 | \tprivate-address: fd00::/8 1269 | \tprivate-address: fe80::/10 1270 | \tdo-ip4: yes 1271 | \tdo-ip6: yes 1272 | \tdo-udp: yes 1273 | \tdo-tcp: yes 1274 | \tchroot: \"\" 1275 | \thide-identity: yes 1276 | \thide-version: yes 1277 | \tharden-glue: yes 1278 | \tharden-dnssec-stripped: yes 1279 | \tharden-referral-path: yes 1280 | \tunwanted-reply-threshold: 10000000 1281 | \tcache-min-ttl: 86400 1282 | \tcache-max-ttl: 2592000 1283 | \tprefetch: yes 1284 | \tqname-minimisation: yes 1285 | \tprefetch-key: yes" 1286 | echo -e "${UNBOUND_TEMP_INTERFACE_INFO}" | awk '!seen[$0]++' >${UNBOUND_CONFIG} 1287 | # Configure block list if INSTALL_BLOCK_LIST is true. 1288 | if [ "${INSTALL_BLOCK_LIST}" == true ]; then 1289 | echo -e "\tinclude: ${UNBOUND_CONFIG_HOST}" >>${UNBOUND_CONFIG} 1290 | if [ ! -d "${UNBOUND_CONFIG_DIRECTORY}" ]; then 1291 | mkdir --parents "${UNBOUND_CONFIG_DIRECTORY}" 1292 | fi 1293 | curl "${UNBOUND_CONFIG_HOST_URL}" | awk '{print "local-zone: \""$1"\" always_refuse"}' >${UNBOUND_CONFIG_HOST} 1294 | fi 1295 | # Update ownership of Unbound's root directory. 1296 | chown --recursive "${USER}":"${USER}" ${UNBOUND_ROOT} 1297 | # Update the resolv.conf file to use Unbound. 1298 | if [ -f "${RESOLV_CONFIG_OLD}" ]; then 1299 | rm --force ${RESOLV_CONFIG_OLD} 1300 | fi 1301 | if [ -f "${RESOLV_CONFIG}" ]; then 1302 | chattr -i ${RESOLV_CONFIG} 1303 | mv ${RESOLV_CONFIG} ${RESOLV_CONFIG_OLD} 1304 | fi 1305 | echo "nameserver 127.0.0.1" >${RESOLV_CONFIG} 1306 | echo "nameserver ::1" >>${RESOLV_CONFIG} 1307 | chattr +i ${RESOLV_CONFIG} 1308 | # Save Unbound status to UNBOUND_MANAGER file. 1309 | echo "Unbound: true" >${UNBOUND_MANAGER} 1310 | # Set CLIENT_DNS to use gateway addresses. 1311 | CLIENT_DNS="${GATEWAY_ADDRESS_V4},${GATEWAY_ADDRESS_V6}" 1312 | fi 1313 | } 1314 | 1315 | # Call the function to install Unbound. 1316 | install-unbound 1317 | 1318 | # Function to configure WireGuard settings 1319 | function wireguard-setconf() { 1320 | # Generate server private and public keys 1321 | SERVER_PRIVKEY=$(wg genkey) 1322 | SERVER_PUBKEY=$(echo "${SERVER_PRIVKEY}" | wg pubkey) 1323 | # Generate client private and public keys 1324 | CLIENT_PRIVKEY=$(wg genkey) 1325 | CLIENT_PUBKEY=$(echo "${CLIENT_PRIVKEY}" | wg pubkey) 1326 | # Assign client IPv4 and IPv6 addresses 1327 | CLIENT_ADDRESS_V4=$(echo "${PRIVATE_SUBNET_V4}" | cut --delimiter="." --fields=1-3).2 1328 | CLIENT_ADDRESS_V6=$(echo "${PRIVATE_SUBNET_V6}" | cut --delimiter=":" --fields=1-4):2 1329 | # Generate pre-shared key and random port for the client 1330 | PRESHARED_KEY=$(wg genpsk) 1331 | PEER_PORT=$(shuf --input-range=1024-65535 --head-count=1) 1332 | # Create the wireguard directory 1333 | mkdir --parents ${WIREGUARD_PATH} 1334 | # Create the client configuration directory 1335 | mkdir --parents ${WIREGUARD_CLIENT_PATH} 1336 | # Set up nftables rules depending on whether Unbound is installed 1337 | if [ "${INSTALL_UNBOUND}" == true ]; then 1338 | # Set up nftables rules for when Unbound is installed 1339 | NFTABLES_POSTUP="sysctl --write net.ipv4.ip_forward=1; sysctl --write net.ipv6.conf.all.forwarding=1; nft add table inet wireguard-${WIREGUARD_PUB_NIC}; nft add chain inet wireguard-${WIREGUARD_PUB_NIC} wireguard_chain {type nat hook postrouting priority srcnat\;}; nft add rule inet wireguard-${WIREGUARD_PUB_NIC} wireguard_chain oifname ${SERVER_PUB_NIC} masquerade" 1340 | NFTABLES_POSTDOWN="sysctl --write net.ipv4.ip_forward=0; sysctl --write net.ipv6.conf.all.forwarding=0; nft delete table inet wireguard-${WIREGUARD_PUB_NIC}" 1341 | else 1342 | # Set up nftables rules for when Unbound is not installed 1343 | NFTABLES_POSTUP="sysctl --write net.ipv4.ip_forward=1; sysctl --write net.ipv6.conf.all.forwarding=1; nft add table inet wireguard-${WIREGUARD_PUB_NIC}; nft add chain inet wireguard-${WIREGUARD_PUB_NIC} PREROUTING {type nat hook prerouting priority 0\;}; nft add chain inet wireguard-${WIREGUARD_PUB_NIC} POSTROUTING {type nat hook postrouting priority 100\;}; nft add rule inet wireguard-${WIREGUARD_PUB_NIC} POSTROUTING ip saddr ${PRIVATE_SUBNET_V4} oifname ${SERVER_PUB_NIC} masquerade; nft add rule inet wireguard-${WIREGUARD_PUB_NIC} POSTROUTING ip6 saddr ${PRIVATE_SUBNET_V6} oifname ${SERVER_PUB_NIC} masquerade" 1344 | NFTABLES_POSTDOWN="sysctl --write net.ipv4.ip_forward=0; sysctl --write net.ipv6.conf.all.forwarding=0; nft delete table inet wireguard-${WIREGUARD_PUB_NIC}" 1345 | fi 1346 | # Create server WireGuard configuration file 1347 | echo "# ${PRIVATE_SUBNET_V4} ${PRIVATE_SUBNET_V6} ${SERVER_HOST}:${SERVER_PORT} ${SERVER_PUBKEY} ${CLIENT_DNS} ${PEER_MTU_CHOICE} ${NAT_CHOICE} ${CLIENT_ALLOWED_IP} 1348 | [Interface] 1349 | Address = ${GATEWAY_ADDRESS_V4}/${PRIVATE_SUBNET_MASK_V4},${GATEWAY_ADDRESS_V6}/${PRIVATE_SUBNET_MASK_V6} 1350 | ListenPort = ${SERVER_PORT} 1351 | MTU = ${INTERFACE_MTU_CHOICE} 1352 | PrivateKey = ${SERVER_PRIVKEY} 1353 | PostUp = ${NFTABLES_POSTUP} 1354 | PostDown = ${NFTABLES_POSTDOWN} 1355 | SaveConfig = false 1356 | # ${CLIENT_NAME} start 1357 | [Peer] 1358 | PublicKey = ${CLIENT_PUBKEY} 1359 | PresharedKey = ${PRESHARED_KEY} 1360 | AllowedIPs = ${CLIENT_ADDRESS_V4}/32,${CLIENT_ADDRESS_V6}/128 1361 | # ${CLIENT_NAME} end" >>${WIREGUARD_CONFIG} 1362 | 1363 | # Generate client-specific WireGuard configuration file 1364 | echo "# ${WIREGUARD_WEBSITE_URL} 1365 | [Interface] 1366 | Address = ${CLIENT_ADDRESS_V4}/${PRIVATE_SUBNET_MASK_V4},${CLIENT_ADDRESS_V6}/${PRIVATE_SUBNET_MASK_V6} 1367 | DNS = ${CLIENT_DNS} 1368 | ListenPort = ${PEER_PORT} 1369 | MTU = ${PEER_MTU_CHOICE} 1370 | PrivateKey = ${CLIENT_PRIVKEY} 1371 | [Peer] 1372 | AllowedIPs = ${CLIENT_ALLOWED_IP} 1373 | Endpoint = ${SERVER_HOST}:${SERVER_PORT} 1374 | PersistentKeepalive = ${NAT_CHOICE} 1375 | PresharedKey = ${PRESHARED_KEY} 1376 | PublicKey = ${SERVER_PUBKEY}" >>${WIREGUARD_CLIENT_PATH}/"${CLIENT_NAME}"-${WIREGUARD_PUB_NIC}.conf 1377 | # Update ownership of the WireGuard configuration directory to root 1378 | chown --recursive root:root ${WIREGUARD_PATH} 1379 | # Apply appropriate permissions to the WireGuard configuration directory 1380 | find ${WIREGUARD_PATH} -type d -exec chmod 700 {} + 1381 | # Apply appropriate permissions to the WireGuard configuration files 1382 | find ${WIREGUARD_PATH} -type f -exec chmod 600 {} + 1383 | # Schedule automatic WireGuard expiration if enabled 1384 | if [ "${AUTOMATIC_WIREGUARD_EXPIRATION}" == true ]; then 1385 | crontab -l | { 1386 | cat 1387 | echo "$(date +%M) $(date +%H) $(date +%d) $(date +%m) * echo -e \"${CLIENT_NAME}\" | ${CURRENT_FILE_PATH} --remove" 1388 | } | crontab - 1389 | fi 1390 | # Initiate and set the necessary services to run at startup, depending on the init system (either systemd or init) 1391 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1392 | systemctl enable --now nftables 1393 | systemctl enable --now wg-quick@${WIREGUARD_PUB_NIC} 1394 | if [ "${INSTALL_UNBOUND}" == true ]; then 1395 | systemctl enable --now unbound 1396 | systemctl restart unbound 1397 | fi 1398 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1399 | service nftables start 1400 | service wg-quick@${WIREGUARD_PUB_NIC} start 1401 | if [ "${INSTALL_UNBOUND}" == true ]; then 1402 | service unbound restart 1403 | fi 1404 | fi 1405 | # Create a QR code for the client configuration for easy scanning 1406 | qrencode -t ansiutf8 <${WIREGUARD_CLIENT_PATH}/"${CLIENT_NAME}"-${WIREGUARD_PUB_NIC}.conf 1407 | # Display the client configuration details in the terminal 1408 | cat ${WIREGUARD_CLIENT_PATH}/"${CLIENT_NAME}"-${WIREGUARD_PUB_NIC}.conf 1409 | # Show the path where the client configuration file is stored 1410 | echo "Client Config --> ${WIREGUARD_CLIENT_PATH}/${CLIENT_NAME}-${WIREGUARD_PUB_NIC}.conf" 1411 | } 1412 | 1413 | # Configuring WireGuard settings 1414 | wireguard-setconf 1415 | 1416 | # After WireGuard Install 1417 | else 1418 | 1419 | # What to do if the software is already installed? 1420 | function wireguard-next-questions-interface() { 1421 | echo "Please select an action:" 1422 | echo " 1) Display WireGuard configuration" 1423 | echo " 2) Initiate WireGuard service" 1424 | echo " 3) Terminate WireGuard service" 1425 | echo " 4) Restart WireGuard service" 1426 | echo " 5) Add a new WireGuard peer (client)" 1427 | echo " 6) Remove a WireGuard peer (client)" 1428 | echo " 7) Reinstall WireGuard service" 1429 | echo " 8) Uninstall WireGuard service" 1430 | echo " 9) Update this management script" 1431 | echo " 10) Backup WireGuard configuration" 1432 | echo " 11) Restore WireGuard configuration" 1433 | echo " 12) Update WireGuard interface IP" 1434 | echo " 13) Update WireGuard interface port" 1435 | echo " 14) Purge all WireGuard peers" 1436 | echo " 15) Generate a QR code for WireGuard configuration" 1437 | echo " 16) Verify WireGuard configurations" 1438 | until [[ "${WIREGUARD_OPTIONS}" =~ ^[0-9]+$ ]] && [ "${WIREGUARD_OPTIONS}" -ge 1 ] && [ "${WIREGUARD_OPTIONS}" -le 16 ]; do 1439 | read -rp "Select an Option [1-16]:" -e -i 0 WIREGUARD_OPTIONS 1440 | done 1441 | case ${WIREGUARD_OPTIONS} in 1442 | 1) # Display WireGuard configuration 1443 | wg show ${WIREGUARD_PUB_NIC} 1444 | ;; 1445 | 2) # Initiate WireGuard service 1446 | wg-quick up ${WIREGUARD_PUB_NIC} 1447 | ;; 1448 | 3) # Terminate WireGuard service 1449 | wg-quick down ${WIREGUARD_PUB_NIC} 1450 | ;; 1451 | 4) # Restart the WireGuard service 1452 | # The script first identifies the init system (either "systemd" or "init") 1453 | # Then, it restarts the WireGuard service based on the identified init system 1454 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1455 | systemctl restart wg-quick@${WIREGUARD_PUB_NIC} 1456 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1457 | service wg-quick@${WIREGUARD_PUB_NIC} restart 1458 | fi 1459 | ;; 1460 | 5) # Adding a new peer to WireGuard 1461 | # If a client name isn't supplied, the script will request one 1462 | if [ -z "${NEW_CLIENT_NAME}" ]; then 1463 | echo "Let's name the WireGuard Peer. Use one word only, no special characters, no spaces." 1464 | read -rp "New client peer:" -e -i "$(openssl rand -hex 25)" NEW_CLIENT_NAME 1465 | fi 1466 | # If no client name is provided, use openssl to generate a random name 1467 | if [ -z "${NEW_CLIENT_NAME}" ]; then 1468 | NEW_CLIENT_NAME="$(openssl rand -hex 25)" 1469 | fi 1470 | # Extract the last IPv4 address used in the WireGuard configuration file 1471 | LASTIPV4=$(grep "AllowedIPs" ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=4 | tail --lines=1) 1472 | # Extract the last IPv6 address used in the WireGuard configuration file 1473 | LASTIPV6=$(grep "AllowedIPs" ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="," --fields=2 | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=5 | tail --lines=1) 1474 | # If no IPv4 and IPv6 addresses are found in the configuration file, set the initial values to 1 1475 | if { [ -z "${LASTIPV4}" ] && [ -z "${LASTIPV6}" ]; }; then 1476 | LASTIPV4=1 1477 | LASTIPV6=1 1478 | fi 1479 | # Find the smallest used IPv4 address in the WireGuard configuration file 1480 | SMALLEST_USED_IPV4=$(grep "AllowedIPs" ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=4 | sort --numeric-sort | head --lines=1) 1481 | # Find the largest used IPv4 address in the WireGuard configuration file 1482 | LARGEST_USED_IPV4=$(grep "AllowedIPs" ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=4 | sort --numeric-sort | tail --lines=1) 1483 | # Create a list of used IPv4 addresses in the WireGuard configuration file 1484 | USED_IPV4_LIST=$(grep "AllowedIPs" ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=4 | sort --numeric-sort) 1485 | # Loop through IPv4 addresses and find an unused one 1486 | while [ "${SMALLEST_USED_IPV4}" -le "${LARGEST_USED_IPV4}" ]; do 1487 | if [[ ! ${USED_IPV4_LIST[*]} =~ ${SMALLEST_USED_IPV4} ]]; then 1488 | FIND_UNUSED_IPV4=${SMALLEST_USED_IPV4} 1489 | break 1490 | fi 1491 | SMALLEST_USED_IPV4=$((SMALLEST_USED_IPV4 + 1)) 1492 | done 1493 | # Find the smallest used IPv6 address in the WireGuard configuration file 1494 | SMALLEST_USED_IPV6=$(grep "AllowedIPs" ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="," --fields=2 | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=5 | sort --numeric-sort | head --lines=1) 1495 | # Find the largest used IPv6 address in the WireGuard configuration file 1496 | LARGEST_USED_IPV6=$(grep "AllowedIPs" ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="," --fields=2 | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=5 | sort --numeric-sort | tail --lines=1) 1497 | # Create a list of used IPv6 addresses in the WireGuard configuration file 1498 | USED_IPV6_LIST=$(grep "AllowedIPs" ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="," --fields=2 | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=5 | sort --numeric-sort) 1499 | # Loop through IPv6 addresses and find an unused one 1500 | while [ "${SMALLEST_USED_IPV6}" -le "${LARGEST_USED_IPV6}" ]; do 1501 | if [[ ! ${USED_IPV6_LIST[*]} =~ ${SMALLEST_USED_IPV6} ]]; then 1502 | FIND_UNUSED_IPV6=${SMALLEST_USED_IPV6} 1503 | break 1504 | fi 1505 | SMALLEST_USED_IPV6=$((SMALLEST_USED_IPV6 + 1)) 1506 | done 1507 | # If unused IPv4 and IPv6 addresses are found, set them as the last IPv4 and IPv6 addresses 1508 | if { [ -n "${FIND_UNUSED_IPV4}" ] && [ -n "${FIND_UNUSED_IPV6}" ]; }; then 1509 | LASTIPV4=$(echo "${FIND_UNUSED_IPV4}" | head --lines=1) 1510 | LASTIPV6=$(echo "${FIND_UNUSED_IPV6}" | head --lines=1) 1511 | fi 1512 | if { [ "${LASTIPV4}" -ge 255 ] && [ "${LASTIPV6}" -ge 255 ]; }; then 1513 | # Get the current IPv4 and IPv6 ranges from the WireGuard config file 1514 | CURRENT_IPV4_RANGE=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2) 1515 | CURRENT_IPV6_RANGE=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3) 1516 | # Get the last octet of the IPv4 range and the fifth hextet of the IPv6 range 1517 | IPV4_BEFORE_BACKSLASH=$(echo "${CURRENT_IPV4_RANGE}" | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=4) 1518 | IPV6_BEFORE_BACKSLASH=$(echo "${CURRENT_IPV6_RANGE}" | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=5) 1519 | # Get the second octet of the IPv4 range and the second hextet of the IPv6 range 1520 | IPV4_AFTER_FIRST=$(echo "${CURRENT_IPV4_RANGE}" | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=2) 1521 | IPV6_AFTER_FIRST=$(echo "${CURRENT_IPV6_RANGE}" | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=2) 1522 | # Get the second and third octets of the IPv4 range and the third and fourth hextets of the IPv6 range 1523 | SECOND_IPV4_IN_RANGE=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2 | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=2) 1524 | SECOND_IPV6_IN_RANGE=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=2) 1525 | THIRD_IPV4_IN_RANGE=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2 | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=3) 1526 | THIRD_IPV6_IN_RANGE=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=3) 1527 | # Calculate the next IPv4 and IPv6 ranges 1528 | NEXT_IPV4_RANGE=$((THIRD_IPV4_IN_RANGE + 1)) 1529 | NEXT_IPV6_RANGE=$((THIRD_IPV6_IN_RANGE + 1)) 1530 | # Get the CIDR notation for the current IPv4 and IPv6 ranges 1531 | CURRENT_IPV4_RANGE_CIDR=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2 | cut --delimiter="/" --fields=2) 1532 | CURRENT_IPV6_RANGE_CIDR=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3 | cut --delimiter="/" --fields=2) 1533 | FINAL_IPV4_RANGE=$(echo "${CURRENT_IPV4_RANGE}" | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=1,2)".${NEXT_IPV4_RANGE}.${IPV4_BEFORE_BACKSLASH}/${CURRENT_IPV4_RANGE_CIDR}" 1534 | FINAL_IPV6_RANGE=$(echo "${CURRENT_IPV6_RANGE}" | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=1,2)":${NEXT_IPV6_RANGE}::${IPV6_BEFORE_BACKSLASH}/${CURRENT_IPV6_RANGE_CIDR}" 1535 | if { [ "${THIRD_IPV4_IN_RANGE}" -ge 255 ] && [ "${THIRD_IPV6_IN_RANGE}" -ge 255 ]; }; then 1536 | if { [ "${SECOND_IPV4_IN_RANGE}" -ge 255 ] && [ "${SECOND_IPV6_IN_RANGE}" -ge 255 ] && [ "${THIRD_IPV4_IN_RANGE}" -ge 255 ] && [ "${THIRD_IPV6_IN_RANGE}" -ge 255 ] && [ "${LASTIPV4}" -ge 255 ] && [ "${LASTIPV6}" -ge 255 ]; }; then 1537 | # If all IP ranges are at their maximum value, then exit with an error message 1538 | echo "Error: You are unable to add any more peers." 1539 | exit 1540 | fi 1541 | # Calculate the next IPv4 and IPv6 ranges 1542 | NEXT_IPV4_RANGE=$((SECOND_IPV4_IN_RANGE + 1)) 1543 | NEXT_IPV6_RANGE=$((SECOND_IPV6_IN_RANGE + 1)) 1544 | # Calculate the final IPv4 and IPv6 ranges 1545 | FINAL_IPV4_RANGE=$(echo "${CURRENT_IPV4_RANGE}" | cut --delimiter="/" --fields=1 | cut --delimiter="." --fields=1)".${NEXT_IPV4_RANGE}.${IPV4_AFTER_FIRST}.${IPV4_BEFORE_BACKSLASH}/${CURRENT_IPV4_RANGE_CIDR}" 1546 | FINAL_IPV6_RANGE=$(echo "${CURRENT_IPV6_RANGE}" | cut --delimiter="/" --fields=1 | cut --delimiter=":" --fields=1)":${NEXT_IPV6_RANGE}:${IPV6_AFTER_FIRST}::${IPV6_BEFORE_BACKSLASH}/${CURRENT_IPV6_RANGE_CIDR}" 1547 | fi 1548 | # Replace the current IPv4 and IPv6 ranges with the final IPv4 and IPv6 ranges in the WireGuard config file 1549 | sed --in-place "1s|${CURRENT_IPV4_RANGE}|${FINAL_IPV4_RANGE}|" ${WIREGUARD_CONFIG} 1550 | sed --in-place "1s|${CURRENT_IPV6_RANGE}|${FINAL_IPV6_RANGE}|" ${WIREGUARD_CONFIG} 1551 | # Set LASTIPV4 and LASTIPV6 to their maximum values to indicate that no more peers can be added 1552 | LASTIPV4=1 1553 | LASTIPV6=1 1554 | fi 1555 | # Generate a private key for the client 1556 | CLIENT_PRIVKEY=$(wg genkey) 1557 | # Derive the public key from the private key 1558 | CLIENT_PUBKEY=$(echo "${CLIENT_PRIVKEY}" | wg pubkey) 1559 | # Generate a preshared key for the client and server to use 1560 | PRESHARED_KEY=$(wg genpsk) 1561 | # Choose a random port number for the peer 1562 | PEER_PORT=$(shuf --input-range=1024-65535 --head-count=1) 1563 | # Get the private subnet and subnet mask from the WireGuard config file 1564 | PRIVATE_SUBNET_V4=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2) 1565 | PRIVATE_SUBNET_MASK_V4=$(echo "${PRIVATE_SUBNET_V4}" | cut --delimiter="/" --fields=2) 1566 | PRIVATE_SUBNET_V6=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=3) 1567 | PRIVATE_SUBNET_MASK_V6=$(echo "${PRIVATE_SUBNET_V6}" | cut --delimiter="/" --fields=2) 1568 | # Get the server host and public key from the WireGuard config file 1569 | SERVER_HOST=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=4) 1570 | SERVER_PUBKEY=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=5) 1571 | # Get the client DNS server, MTU choice, NAT choice, and allowed IP address from the WireGuard config file 1572 | CLIENT_DNS=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=6) 1573 | MTU_CHOICE=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=7) 1574 | NAT_CHOICE=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=8) 1575 | CLIENT_ALLOWED_IP=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=9) 1576 | # Calculate the client's IP addresses based on the last IP addresses used 1577 | CLIENT_ADDRESS_V4=$(echo "${PRIVATE_SUBNET_V4}" | cut --delimiter="." --fields=1-3).$((LASTIPV4 + 1)) 1578 | CLIENT_ADDRESS_V6=$(echo "${PRIVATE_SUBNET_V6}" | cut --delimiter=":" --fields=1-4):$((LASTIPV6 + 1)) 1579 | # Check if there are any unused IP addresses available 1580 | if { [ -n "${FIND_UNUSED_IPV4}" ] && [ -n "${FIND_UNUSED_IPV6}" ]; }; then 1581 | CLIENT_ADDRESS_V4=$(echo "${CLIENT_ADDRESS_V4}" | cut --delimiter="." --fields=1-3).${LASTIPV4} 1582 | CLIENT_ADDRESS_V6=$(echo "${CLIENT_ADDRESS_V6}" | cut --delimiter=":" --fields=1-4):${LASTIPV6} 1583 | fi 1584 | # Create a temporary file to store the new client information 1585 | WIREGUARD_TEMP_NEW_CLIENT_INFO="# ${NEW_CLIENT_NAME} start 1586 | [Peer] 1587 | PublicKey = ${CLIENT_PUBKEY} 1588 | PresharedKey = ${PRESHARED_KEY} 1589 | AllowedIPs = ${CLIENT_ADDRESS_V4}/32,${CLIENT_ADDRESS_V6}/128 1590 | # ${NEW_CLIENT_NAME} end" 1591 | # Write the temporary new client information to the 'add peer' configuration file 1592 | echo "${WIREGUARD_TEMP_NEW_CLIENT_INFO}" >${WIREGUARD_ADD_PEER_CONFIG} 1593 | # Add the new peer configuration to the WireGuard interface 1594 | wg addconf ${WIREGUARD_PUB_NIC} ${WIREGUARD_ADD_PEER_CONFIG} 1595 | # If there are no unused IPv4 and IPv6 addresses, append the new client information to the WireGuard configuration file 1596 | if { [ -z "${FIND_UNUSED_IPV4}" ] && [ -z "${FIND_UNUSED_IPV6}" ]; }; then 1597 | echo "${WIREGUARD_TEMP_NEW_CLIENT_INFO}" >>${WIREGUARD_CONFIG} 1598 | # If there are unused IPv4 and IPv6 addresses, modify the 'add peer' configuration file and insert the new client information into the WireGuard configuration file 1599 | elif { [ -n "${FIND_UNUSED_IPV4}" ] && [ -n "${FIND_UNUSED_IPV6}" ]; }; then 1600 | sed --in-place "s|$|\\\n|" "${WIREGUARD_ADD_PEER_CONFIG}" 1601 | sed --in-place "6s|\\\n||" "${WIREGUARD_ADD_PEER_CONFIG}" 1602 | # Remove newline characters from the 'add peer' configuration file 1603 | WIREGUARD_TEMPORARY_PEER_DATA=$(tr --delete "\n" <"${WIREGUARD_ADD_PEER_CONFIG}") 1604 | # Calculate the line number where the new client information should be inserted 1605 | TEMP_WRITE_LINE=$((LASTIPV4 - 2)) 1606 | # Insert the new client information into the WireGuard configuration file 1607 | sed --in-place $((TEMP_WRITE_LINE * 6 + 11))i"${WIREGUARD_TEMPORARY_PEER_DATA}" ${WIREGUARD_CONFIG} 1608 | fi 1609 | # Remove the wireguard add peer config file 1610 | rm --force ${WIREGUARD_ADD_PEER_CONFIG} 1611 | # Create the client configuration file 1612 | echo "# ${WIREGUARD_WEBSITE_URL} 1613 | [Interface] 1614 | Address = ${CLIENT_ADDRESS_V4}/${PRIVATE_SUBNET_MASK_V4},${CLIENT_ADDRESS_V6}/${PRIVATE_SUBNET_MASK_V6} 1615 | DNS = ${CLIENT_DNS} 1616 | ListenPort = ${PEER_PORT} 1617 | MTU = ${MTU_CHOICE} 1618 | PrivateKey = ${CLIENT_PRIVKEY} 1619 | [Peer] 1620 | AllowedIPs = ${CLIENT_ALLOWED_IP} 1621 | Endpoint = ${SERVER_HOST} 1622 | PersistentKeepalive = ${NAT_CHOICE} 1623 | PresharedKey = ${PRESHARED_KEY} 1624 | PublicKey = ${SERVER_PUBKEY}" >>${WIREGUARD_CLIENT_PATH}/"${NEW_CLIENT_NAME}"-${WIREGUARD_PUB_NIC}.conf 1625 | # Add the WireGuard interface configuration, stripping any unnecessary fields 1626 | wg addconf ${WIREGUARD_PUB_NIC} <(wg-quick strip ${WIREGUARD_PUB_NIC}) 1627 | # Check if automatic WireGuard expiration is enabled, and if so, set the expiration date 1628 | if crontab -l | grep -q "${CURRENT_FILE_PATH} --remove"; then 1629 | crontab -l | { 1630 | cat 1631 | # Add a new cron job to remove the new client at the specified expiration date 1632 | echo "$(date +%M) $(date +%H) $(date +%d) $(date +%m) * echo -e \"${NEW_CLIENT_NAME}\" | ${CURRENT_FILE_PATH} --remove" 1633 | } | crontab - 1634 | fi 1635 | # Generate and display a QR code for the new client configuration 1636 | qrencode -t ansiutf8 <${WIREGUARD_CLIENT_PATH}/"${NEW_CLIENT_NAME}"-${WIREGUARD_PUB_NIC}.conf 1637 | # Output the new client configuration file content 1638 | cat ${WIREGUARD_CLIENT_PATH}/"${NEW_CLIENT_NAME}"-${WIREGUARD_PUB_NIC}.conf 1639 | # Display the path of the new client configuration file 1640 | echo "Client config --> ${WIREGUARD_CLIENT_PATH}/${NEW_CLIENT_NAME}-${WIREGUARD_PUB_NIC}.conf" 1641 | ;; 1642 | 6) # Remove WireGuard Peer 1643 | # Prompt the user to choose a WireGuard peer to remove 1644 | echo "Which WireGuard peer would you like to remove?" 1645 | # List all the peers' names in the WireGuard configuration file 1646 | grep start ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2 1647 | # Read the user input for the peer's name 1648 | read -rp "Peer's name:" REMOVECLIENT 1649 | # Extract the public key of the selected peer from the configuration file 1650 | CLIENTKEY=$(sed -n "/\# ${REMOVECLIENT} start/,/\# ${REMOVECLIENT} end/p" ${WIREGUARD_CONFIG} | grep PublicKey | cut --delimiter=" " --fields=3) 1651 | # Remove the selected peer from the WireGuard interface using the extracted public key 1652 | wg set ${WIREGUARD_PUB_NIC} peer "${CLIENTKEY}" remove 1653 | # Remove the selected peer's configuration block from the WireGuard configuration file 1654 | sed --in-place "/\# ${REMOVECLIENT} start/,/\# ${REMOVECLIENT} end/d" ${WIREGUARD_CONFIG} 1655 | # If the selected peer has a configuration file in the client path, remove it 1656 | if [ -f "${WIREGUARD_CLIENT_PATH}/${REMOVECLIENT}-${WIREGUARD_PUB_NIC}.conf" ]; then 1657 | rm --force ${WIREGUARD_CLIENT_PATH}/"${REMOVECLIENT}"-${WIREGUARD_PUB_NIC}.conf 1658 | fi 1659 | # Reload the WireGuard interface configuration to apply the changes 1660 | wg addconf ${WIREGUARD_PUB_NIC} <(wg-quick strip ${WIREGUARD_PUB_NIC}) 1661 | # Remove any cronjobs associated with the removed peer 1662 | crontab -l | grep --invert-match "${REMOVECLIENT}" | crontab - 1663 | ;; 1664 | 7) # Reinstall WireGuard 1665 | # Check if the current init system is systemd, and if so, disable and stop the WireGuard service 1666 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1667 | systemctl disable --now wg-quick@${WIREGUARD_PUB_NIC} 1668 | # Check if the current init system is init, and if so, stop the WireGuard service 1669 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1670 | service wg-quick@${WIREGUARD_PUB_NIC} stop 1671 | fi 1672 | # Bring down the WireGuard interface 1673 | wg-quick down ${WIREGUARD_PUB_NIC} 1674 | # Reinstall or update WireGuard based on the current Linux distribution 1675 | if { [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "raspbian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ]; }; then 1676 | dpkg-reconfigure wireguard-dkms 1677 | modprobe wireguard 1678 | elif { [ "${CURRENT_DISTRO}" == "fedora" ] || [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "rhel" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 1679 | yum reinstall wireguard-tools -y 1680 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 1681 | pacman -Su --noconfirm wireguard-tools 1682 | elif [ "${CURRENT_DISTRO}" == "alpine" ]; then 1683 | apk fix wireguard-tools 1684 | elif [ "${CURRENT_DISTRO}" == "freebsd" ]; then 1685 | pkg check wireguard 1686 | elif [ "${CURRENT_DISTRO}" == "ol" ]; then 1687 | yum reinstall wireguard-tools -y 1688 | fi 1689 | # Enable and start the WireGuard service based on the current init system 1690 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1691 | systemctl enable --now wg-quick@${WIREGUARD_PUB_NIC} 1692 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1693 | service wg-quick@${WIREGUARD_PUB_NIC} restart 1694 | fi 1695 | ;; 1696 | 8) # Uninstall WireGuard and purging files 1697 | # Check if the current init system is systemd and disable the WireGuard service 1698 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1699 | systemctl disable --now wg-quick@${WIREGUARD_PUB_NIC} 1700 | # If the init system is not systemd, check if it is init and stop the WireGuard service 1701 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1702 | service wg-quick@${WIREGUARD_PUB_NIC} stop 1703 | fi 1704 | # Bring down the WireGuard interface 1705 | wg-quick down ${WIREGUARD_PUB_NIC} 1706 | # Removing Wireguard Files 1707 | # Check if the WireGuard directory exists and remove it 1708 | if [ -d "${WIREGUARD_PATH}" ]; then 1709 | rm --recursive --force ${WIREGUARD_PATH} 1710 | fi 1711 | # Remove WireGuard and qrencode packages based on the current distribution 1712 | # For CentOS, AlmaLinux, and Rocky Linux distributions 1713 | if { [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 1714 | yum remove wireguard qrencode -y 1715 | # For Ubuntu, Debian, Raspbian, Pop!_OS, Kali Linux, Linux Mint, and KDE Neon distributions 1716 | elif { [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "raspbian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ]; }; then 1717 | apt-get remove --purge wireguard qrencode -y 1718 | # Remove backports repository and keys if they exist 1719 | if [ -f "/etc/apt/sources.list.d/backports.list" ]; then 1720 | rm --force /etc/apt/sources.list.d/backports.list 1721 | apt-key del 648ACFD622F3D138 1722 | apt-key del 0E98404D386FA1D9 1723 | fi 1724 | # For Arch, Arch ARM, and Manjaro distributions 1725 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 1726 | pacman -Rs --noconfirm wireguard-tools qrencode 1727 | # For Fedora distribution 1728 | elif [ "${CURRENT_DISTRO}" == "fedora" ]; then 1729 | dnf remove wireguard qrencode -y 1730 | # Remove WireGuard repository if it exists 1731 | if [ -f "/etc/yum.repos.d/wireguard.repo" ]; then 1732 | rm --force /etc/yum.repos.d/wireguard.repo 1733 | fi 1734 | # For RHEL distribution 1735 | elif [ "${CURRENT_DISTRO}" == "rhel" ]; then 1736 | yum remove wireguard qrencode -y 1737 | # Remove WireGuard repository if it exists 1738 | if [ -f "/etc/yum.repos.d/wireguard.repo" ]; then 1739 | rm --force /etc/yum.repos.d/wireguard.repo 1740 | fi 1741 | # For Alpine Linux distribution 1742 | elif [ "${CURRENT_DISTRO}" == "alpine" ]; then 1743 | apk del wireguard-tools libqrencode 1744 | # For FreeBSD distribution 1745 | elif [ "${CURRENT_DISTRO}" == "freebsd" ]; then 1746 | pkg delete wireguard libqrencode 1747 | # For Oracle Linux distribution 1748 | elif [ "${CURRENT_DISTRO}" == "ol" ]; then 1749 | yum remove wireguard qrencode -y 1750 | fi 1751 | # Delete WireGuard backup 1752 | if [ -f "${WIREGUARD_CONFIG_BACKUP}" ]; then 1753 | rm --force ${WIREGUARD_CONFIG_BACKUP} 1754 | if [ -f "${WIREGUARD_BACKUP_PASSWORD_PATH}" ]; then 1755 | rm --force "${WIREGUARD_BACKUP_PASSWORD_PATH}" 1756 | fi 1757 | fi 1758 | # Uninstall unbound 1759 | # Check if the 'unbound' command is available on the system 1760 | if [ -x "$(command -v unbound)" ]; then 1761 | # Check if the current init system is systemd and disable the Unbound service 1762 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1763 | systemctl disable --now unbound 1764 | # If the init system is not systemd, check if it is init and stop the Unbound service 1765 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1766 | service unbound stop 1767 | fi 1768 | # If a backup of the resolv.conf file exists, restore it and set the immutable flag 1769 | if [ -f "${RESOLV_CONFIG_OLD}" ]; then 1770 | chattr -i ${RESOLV_CONFIG} 1771 | rm --force ${RESOLV_CONFIG} 1772 | mv ${RESOLV_CONFIG_OLD} ${RESOLV_CONFIG} 1773 | chattr +i ${RESOLV_CONFIG} 1774 | fi 1775 | # Remove Unbound package based on the current distribution 1776 | # For CentOS, RHEL, AlmaLinux, and Rocky Linux distributions 1777 | if { [ "${CURRENT_DISTRO}" == "centos" ] || [ "${CURRENT_DISTRO}" == "rhel" ] || [ "${CURRENT_DISTRO}" == "almalinux" ] || [ "${CURRENT_DISTRO}" == "rocky" ]; }; then 1778 | yum remove unbound -y 1779 | # For Ubuntu, Debian, Raspbian, Pop!_OS, Kali Linux, Linux Mint, and KDE Neon distributions 1780 | elif { [ "${CURRENT_DISTRO}" == "ubuntu" ] || [ "${CURRENT_DISTRO}" == "debian" ] || [ "${CURRENT_DISTRO}" == "raspbian" ] || [ "${CURRENT_DISTRO}" == "pop" ] || [ "${CURRENT_DISTRO}" == "kali" ] || [ "${CURRENT_DISTRO}" == "linuxmint" ] || [ "${CURRENT_DISTRO}" == "neon" ]; }; then 1781 | # If the distribution is Ubuntu, restart systemd-resolved service based on the init system 1782 | if [ "${CURRENT_DISTRO}" == "ubuntu" ]; then 1783 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1784 | systemctl enable --now systemd-resolved 1785 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1786 | service systemd-resolved restart 1787 | fi 1788 | fi 1789 | apt-get remove --purge unbound -y 1790 | # For Arch, Arch ARM, and Manjaro distributions 1791 | elif { [ "${CURRENT_DISTRO}" == "arch" ] || [ "${CURRENT_DISTRO}" == "archarm" ] || [ "${CURRENT_DISTRO}" == "manjaro" ]; }; then 1792 | pacman -Rs --noconfirm unbound 1793 | # For Fedora and Oracle Linux distributions 1794 | elif { [ "${CURRENT_DISTRO}" == "fedora" ] || [ "${CURRENT_DISTRO}" == "ol" ]; }; then 1795 | yum remove unbound -y 1796 | # For Alpine Linux distribution 1797 | elif [ "${CURRENT_DISTRO}" == "alpine" ]; then 1798 | apk del unbound 1799 | # For FreeBSD distribution 1800 | elif [ "${CURRENT_DISTRO}" == "freebsd" ]; then 1801 | pkg delete unbound 1802 | fi 1803 | # Remove Unbound root directory if it exists 1804 | if [ -d "${UNBOUND_ROOT}" ]; then 1805 | rm --recursive --force ${UNBOUND_ROOT} 1806 | fi 1807 | # Remove Unbound root anchor file if it exists 1808 | if [ -f "${UNBOUND_ANCHOR}" ]; then 1809 | rm --force ${UNBOUND_ANCHOR} 1810 | fi 1811 | fi 1812 | # If any cronjobs are identified, they should be removed. 1813 | crontab -l | grep --invert-match "${CURRENT_FILE_PATH}" | crontab - 1814 | ;; 1815 | 9) # Update WireGuard Manager script. 1816 | # Calculate the SHA3-512 hash of the current WireGuard Manager script 1817 | CURRENT_WIREGUARD_MANAGER_HASH=$(openssl dgst -sha3-512 "${CURRENT_FILE_PATH}" | cut --delimiter=" " --fields=2) 1818 | # Calculate the SHA3-512 hash of the latest WireGuard Manager script from the remote source 1819 | NEW_WIREGUARD_MANAGER_HASH=$(curl --silent "${WIREGUARD_MANAGER_UPDATE}" | openssl dgst -sha3-512 | cut --delimiter=" " --fields=2) 1820 | # If the hashes don't match, update the local WireGuard Manager script 1821 | if [ "${CURRENT_WIREGUARD_MANAGER_HASH}" != "${NEW_WIREGUARD_MANAGER_HASH}" ]; then 1822 | curl "${WIREGUARD_MANAGER_UPDATE}" -o "${CURRENT_FILE_PATH}" 1823 | chmod +x "${CURRENT_FILE_PATH}" 1824 | echo "Updating WireGuard Manager script..." 1825 | fi 1826 | # Update the unbound configs if the unbound command is available on the system 1827 | if [ -x "$(command -v unbound)" ]; then 1828 | # Update the unbound root hints file if it exists 1829 | if [ -f "${UNBOUND_ROOT_HINTS}" ]; then 1830 | CURRENT_ROOT_HINTS_HASH=$(openssl dgst -sha3-512 "${UNBOUND_ROOT_HINTS}" | cut --delimiter=" " --fields=2) 1831 | NEW_ROOT_HINTS_HASH=$(curl --silent "${UNBOUND_ROOT_SERVER_CONFIG_URL}" | openssl dgst -sha3-512 | cut --delimiter=" " --fields=2) 1832 | if [ "${CURRENT_ROOT_HINTS_HASH}" != "${NEW_ROOT_HINTS_HASH}" ]; then 1833 | curl "${UNBOUND_ROOT_SERVER_CONFIG_URL}" -o ${UNBOUND_ROOT_HINTS} 1834 | echo "Updating root hints file..." 1835 | fi 1836 | fi 1837 | # Update the unbound config host file if it exists 1838 | if [ -f "${UNBOUND_CONFIG_HOST}" ]; then 1839 | CURRENT_UNBOUND_HOSTS_HASH=$(openssl dgst -sha3-512 "${UNBOUND_CONFIG_HOST}" | cut --delimiter=" " --fields=2) 1840 | NEW_UNBOUND_HOSTS_HASH=$(curl --silent "${UNBOUND_CONFIG_HOST_URL}" | awk '{print "local-zone: \""$1"\" always_refuse"}' | openssl dgst -sha3-512 | cut --delimiter=" " --fields=2) 1841 | if [ "${CURRENT_UNBOUND_HOSTS_HASH}" != "${NEW_UNBOUND_HOSTS_HASH}" ]; then 1842 | curl "${UNBOUND_CONFIG_HOST_URL}" | awk '{print "local-zone: \""$1"\" always_refuse"}' >${UNBOUND_CONFIG_HOST} 1843 | echo "Updating unbound config host file..." 1844 | fi 1845 | fi 1846 | # Once everything is completed, restart the unbound service 1847 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1848 | systemctl restart unbound 1849 | echo "Restarting unbound service..." 1850 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1851 | service unbound restart 1852 | echo "Restarting unbound service..." 1853 | fi 1854 | fi 1855 | ;; 1856 | 10) # Backup WireGuard Config 1857 | # If the WireGuard config backup file exists, remove it 1858 | if [ -f "${WIREGUARD_CONFIG_BACKUP}" ]; then 1859 | rm --force ${WIREGUARD_CONFIG_BACKUP} 1860 | echo "Removing existing backup..." 1861 | fi 1862 | # If the system backup path directory does not exist, create it along with any necessary parent directories 1863 | if [ ! -d "${SYSTEM_BACKUP_PATH}" ]; then 1864 | mkdir --parents ${SYSTEM_BACKUP_PATH} 1865 | echo "Creating backup directory..." 1866 | fi 1867 | # If the WireGuard path directory exists, proceed with the backup process 1868 | if [ -d "${WIREGUARD_PATH}" ]; then 1869 | # Generate a random 50-character hexadecimal backup password and store it in a file 1870 | BACKUP_PASSWORD="$(openssl rand -hex 25)" 1871 | echo "${BACKUP_PASSWORD}" >"${WIREGUARD_BACKUP_PASSWORD_PATH}" 1872 | # Zip the WireGuard config file using the generated backup password and save it as a backup 1873 | zip -P "${BACKUP_PASSWORD}" -rj ${WIREGUARD_CONFIG_BACKUP} ${WIREGUARD_CONFIG} 1874 | # Echo the backup password and path to the terminal 1875 | echo "Backup Password: ${BACKUP_PASSWORD}" 1876 | echo "Backup Path: ${WIREGUARD_CONFIG_BACKUP}" 1877 | echo "Please save the backup password and path in a secure location." 1878 | fi 1879 | ;; 1880 | 11) # Restore WireGuard Config 1881 | # Check if the WireGuard config backup file does not exist, and if so, exit the script 1882 | if [ ! -f "${WIREGUARD_CONFIG_BACKUP}" ]; then 1883 | echo "Error: The WireGuard configuration backup file could not be found. Please ensure it exists and try again." 1884 | exit 1885 | fi 1886 | # Prompt the user to enter the backup password and store it in the WIREGUARD_BACKUP_PASSWORD variable 1887 | read -rp "Backup Password: " -e -i "$(cat "${WIREGUARD_BACKUP_PASSWORD_PATH}")" WIREGUARD_BACKUP_PASSWORD 1888 | # If the WIREGUARD_BACKUP_PASSWORD variable is empty, exit the script 1889 | if [ -z "${WIREGUARD_BACKUP_PASSWORD}" ]; then 1890 | echo "Error: The backup password field is empty. Please provide a valid password." 1891 | exit 1892 | fi 1893 | # Unzip the backup file, overwriting existing files, using the specified backup password, and extract the contents to the WireGuard path 1894 | unzip -o -P "${WIREGUARD_BACKUP_PASSWORD}" "${WIREGUARD_CONFIG_BACKUP}" -d "${WIREGUARD_PATH}" 1895 | # If the current init system is systemd, enable and start the wg-quick service 1896 | if [[ "${CURRENT_INIT_SYSTEM}" == *"systemd"* ]]; then 1897 | systemctl enable --now wg-quick@${WIREGUARD_PUB_NIC} 1898 | # If the current init system is init, restart the wg-quick service 1899 | elif [[ "${CURRENT_INIT_SYSTEM}" == *"init"* ]]; then 1900 | service wg-quick@${WIREGUARD_PUB_NIC} restart 1901 | fi 1902 | ;; 1903 | 12) # Change the IP address of your wireguard interface. 1904 | get-network-information 1905 | # Extract the current IP address method from the WireGuard config file 1906 | CURRENT_IP_METHORD=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=4) 1907 | # If the current IP address method is IPv4, extract the old server host and set the new server host to DEFAULT_INTERFACE_IPV4 1908 | if [[ ${CURRENT_IP_METHORD} != *"["* ]]; then 1909 | OLD_SERVER_HOST=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=4 | cut --delimiter=":" --fields=1) 1910 | NEW_SERVER_HOST=${DEFAULT_INTERFACE_IPV4} 1911 | fi 1912 | # If the current IP address method is IPv6, extract the old server host and set the new server host to DEFAULT_INTERFACE_IPV6 1913 | if [[ ${CURRENT_IP_METHORD} == *"["* ]]; then 1914 | OLD_SERVER_HOST=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=4 | cut --delimiter="[" --fields=2 | cut --delimiter="]" --fields=1) 1915 | NEW_SERVER_HOST=${DEFAULT_INTERFACE_IPV6} 1916 | fi 1917 | # If the old server host is different from the new server host, update the server host in the WireGuard config file 1918 | if [ "${OLD_SERVER_HOST}" != "${NEW_SERVER_HOST}" ]; then 1919 | sed --in-place "1s/${OLD_SERVER_HOST}/${NEW_SERVER_HOST}/" ${WIREGUARD_CONFIG} 1920 | fi 1921 | # Create a list of existing WireGuard clients from the WireGuard config file 1922 | COMPLETE_CLIENT_LIST=$(grep start ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2) 1923 | # Add the clients to the USER_LIST array 1924 | for CLIENT_LIST_ARRAY in ${COMPLETE_CLIENT_LIST}; do 1925 | USER_LIST[ADD_CONTENT]=${CLIENT_LIST_ARRAY} 1926 | ADD_CONTENT=$(("${ADD_CONTENT}" + 1)) 1927 | done 1928 | # Loop through the clients in the USER_LIST array 1929 | for CLIENT_NAME in "${USER_LIST[@]}"; do 1930 | # Check if the client's config file exists 1931 | if [ -f "${WIREGUARD_CLIENT_PATH}/${CLIENT_NAME}-${WIREGUARD_PUB_NIC}.conf" ]; then 1932 | # Update the server host in the client's config file 1933 | sed --in-place "s/${OLD_SERVER_HOST}/${NEW_SERVER_HOST}/" "${WIREGUARD_CLIENT_PATH}/${CLIENT_NAME}-${WIREGUARD_PUB_NIC}.conf" 1934 | fi 1935 | done 1936 | ;; 1937 | 13) # Change the wireguard interface's port number. 1938 | # Extract the old server port from the WireGuard config file 1939 | OLD_SERVER_PORT=$(head --lines=1 ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=4 | cut --delimiter=":" --fields=2) 1940 | # Prompt the user to enter a valid custom port (between 1 and 65535) and store it in NEW_SERVER_PORT 1941 | until [[ "${NEW_SERVER_PORT}" =~ ^[0-9]+$ ]] && [ "${NEW_SERVER_PORT}" -ge 1 ] && [ "${NEW_SERVER_PORT}" -le 65535 ]; do 1942 | read -rp "Enter a custom port number (between 1 and 65535): " -e -i 51820 NEW_SERVER_PORT 1943 | done 1944 | # Check if the chosen port is already in use by another application 1945 | if [ "$(lsof -i UDP:"${NEW_SERVER_PORT}")" ]; then 1946 | # If the port is in use, print an error message and exit the script 1947 | echo "Error: The port number ${NEW_SERVER_PORT} is already in use by another application. Please try a different port number." 1948 | exit 1949 | fi 1950 | # If the old server port is different from the new server port, update the server port in the WireGuard config file 1951 | if [ "${OLD_SERVER_PORT}" != "${NEW_SERVER_PORT}" ]; then 1952 | sed --in-place "s/${OLD_SERVER_PORT}/${NEW_SERVER_PORT}/g" ${WIREGUARD_CONFIG} 1953 | echo "The server port has changed from ${OLD_SERVER_PORT} to ${NEW_SERVER_PORT} in ${WIREGUARD_CONFIG}." 1954 | fi 1955 | # Create a list of existing WireGuard clients from the WireGuard config file 1956 | COMPLETE_CLIENT_LIST=$(grep start ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2) 1957 | # Add the clients to the USER_LIST array 1958 | for CLIENT_LIST_ARRAY in ${COMPLETE_CLIENT_LIST}; do 1959 | USER_LIST[ADD_CONTENT]=${CLIENT_LIST_ARRAY} 1960 | ADD_CONTENT=$(("${ADD_CONTENT}" + 1)) 1961 | done 1962 | # Loop through the clients in the USER_LIST array 1963 | for CLIENT_NAME in "${USER_LIST[@]}"; do 1964 | # Check if the client's config file exists 1965 | if [ -f "${WIREGUARD_CLIENT_PATH}/${CLIENT_NAME}-${WIREGUARD_PUB_NIC}.conf" ]; then 1966 | # Update the server port in the client's config file 1967 | sed --in-place "s/${OLD_SERVER_PORT}/${NEW_SERVER_PORT}/" "${WIREGUARD_CLIENT_PATH}/${CLIENT_NAME}-${WIREGUARD_PUB_NIC}.conf" 1968 | echo "The server port has changed from ${OLD_SERVER_PORT} to ${NEW_SERVER_PORT} in ${WIREGUARD_CLIENT_PATH}/${CLIENT_NAME}-${WIREGUARD_PUB_NIC}.conf." 1969 | fi 1970 | done 1971 | ;; 1972 | 14) # Remove all the peers from the interface. 1973 | COMPLETE_CLIENT_LIST=$(grep start ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2) 1974 | # This line gets the list of clients in the config file by searching for the string "start" and then extracting the second field (the client name) from each line. 1975 | for CLIENT_LIST_ARRAY in ${COMPLETE_CLIENT_LIST}; do 1976 | USER_LIST[ADD_CONTENT]=${CLIENT_LIST_ARRAY} 1977 | ADD_CONTENT=$(("${ADD_CONTENT}" + 1)) 1978 | done 1979 | # This loop iterates over each client in the list and adds it to an array called USER_LIST. 1980 | for CLIENT_NAME in "${USER_LIST[@]}"; do 1981 | CLIENTKEY=$(sed -n "/\# ${CLIENT_NAME} start/,/\# ${CLIENT_NAME} end/p" ${WIREGUARD_CONFIG} | grep PublicKey | cut --delimiter=" " --fields=3) 1982 | # This line extracts the client's public key from the config file. 1983 | wg set ${WIREGUARD_PUB_NIC} peer "${CLIENTKEY}" remove 1984 | # This line removes the client from the server. 1985 | sed --in-place "/\# ${CLIENT_NAME} start/,/\# ${CLIENT_NAME} end/d" ${WIREGUARD_CONFIG} 1986 | # This line removes the client's config from the server. 1987 | if [ -f "${WIREGUARD_CLIENT_PATH}/${CLIENT_NAME}-${WIREGUARD_PUB_NIC}.conf" ]; then 1988 | rm --force ${WIREGUARD_CLIENT_PATH}/"${CLIENT_NAME}"-${WIREGUARD_PUB_NIC}.conf 1989 | else 1990 | echo "The client config file for ${CLIENT_NAME} does not exist." 1991 | fi 1992 | # This line removes the client's config file from the server. 1993 | wg addconf ${WIREGUARD_PUB_NIC} <(wg-quick strip ${WIREGUARD_PUB_NIC}) 1994 | # This line removes the client's config from the running server. 1995 | crontab -l | grep --invert-match "${CLIENT_NAME}" | crontab - 1996 | # This line removes the client from the cron job. 1997 | done 1998 | ;; 1999 | 15) # Generate a QR code for a WireGuard peer. 2000 | # Print a prompt asking the user to choose a WireGuard peer for generating a QR code 2001 | echo "Which WireGuard peer would you like to generate a QR code for?" 2002 | # Extract and display a list of peer names from the WireGuard config file 2003 | grep start ${WIREGUARD_CONFIG} | cut --delimiter=" " --fields=2 2004 | # Prompt the user to enter the desired peer's name and store it in the VIEW_CLIENT_INFO variable 2005 | read -rp "Enter the name of the peer you want to view information for: " VIEW_CLIENT_INFO 2006 | # Check if the config file for the specified peer exists 2007 | if [ -f "${WIREGUARD_CLIENT_PATH}/${VIEW_CLIENT_INFO}-${WIREGUARD_PUB_NIC}.conf" ]; then 2008 | # Generate a QR code for the specified peer's config file and display it in the terminal 2009 | qrencode -t ansiutf8 <${WIREGUARD_CLIENT_PATH}/"${VIEW_CLIENT_INFO}"-${WIREGUARD_PUB_NIC}.conf 2010 | # Print the file path of the specified peer's config file 2011 | echo "Peer's config --> ${WIREGUARD_CLIENT_PATH}/${VIEW_CLIENT_INFO}-${WIREGUARD_PUB_NIC}.conf" 2012 | else 2013 | # If the config file for the specified peer does not exist, print an error message 2014 | echo "Error: The peer you specified could not be found. Please ensure you've entered the correct information." 2015 | exit 2016 | fi 2017 | ;; 2018 | 16) 2019 | # Check if the `unbound` command is available on the system by checking if it is executable 2020 | if [ -x "$(command -v unbound)" ]; then 2021 | # Check if the output of `unbound-checkconf` run on `UNBOUND_CONFIG` contains "no errors" 2022 | if [[ "$(unbound-checkconf ${UNBOUND_CONFIG})" != *"no errors"* ]]; then 2023 | # If "no errors" was not found in output of previous command, print an error message 2024 | "$(unbound-checkconf ${UNBOUND_CONFIG})" 2025 | echo "Error: We found an error on your unbound config file located at ${UNBOUND_CONFIG}" 2026 | exit 2027 | fi 2028 | # Check if output of `unbound-host` run on `UNBOUND_CONFIG` with arguments `-C`, `-v`, and `cloudflare.com` contains "secure" 2029 | if [[ "$(unbound-host -C ${UNBOUND_CONFIG} -v cloudflare.com)" != *"secure"* ]]; then 2030 | # If "secure" was not found in output of previous command, print an error message 2031 | "$(unbound-host -C ${UNBOUND_CONFIG} -v cloudflare.com)" 2032 | echo "Error: We found an error on your unbound DNS-SEC config file loacted at ${UNBOUND_CONFIG}" 2033 | exit 2034 | fi 2035 | echo "Your unbound config file located at ${UNBOUND_CONFIG} is valid." 2036 | fi 2037 | # Check if the `wg` command is available on the system by checking if it is executable 2038 | if [ -x "$(command -v wg)" ]; then 2039 | # Check if the output of `wg` contains "interface" and "public key" 2040 | if [[ "$(wg)" != *"interface"* ]] && [[ "$(wg)" != *"public key"* ]]; then 2041 | # If "interface" and "public key" were not found in output of previous command, print an error message 2042 | echo "Error: We found an error on your WireGuard interface." 2043 | exit 2044 | fi 2045 | echo "Your WireGuard interface is valid." 2046 | fi 2047 | ;; 2048 | esac 2049 | } 2050 | 2051 | # Running Questions Command 2052 | wireguard-next-questions-interface 2053 | 2054 | fi 2055 | --------------------------------------------------------------------------------