From 9a19430dc8355eb96cf023939e460dd71c27c03e Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Fri, 12 Jul 2024 19:22:15 +0200 Subject: [PATCH 1/7] feat: generate PASSWORD_HASH on the fly * remove PASSWORD environment variable in favor of PASSWORD_HASH * enhance password validity check server function * update Dockerfile to include building a binary for generating hashed password * update README with comprehensive Docker usage instructions hash generation --- .dockerignore | 4 +- Dockerfile | 12 ++ README.md | 2 +- src/config.js | 1 - src/lib/Server.js | 11 +- wg-password/.gitignore | 2 + wg-password/Cargo.lock | 357 ++++++++++++++++++++++++++++++++++++++++ wg-password/Cargo.toml | 17 ++ wg-password/PASSWORD.md | 25 +++ wg-password/src/main.rs | 39 +++++ 10 files changed, 458 insertions(+), 12 deletions(-) create mode 100644 wg-password/.gitignore create mode 100644 wg-password/Cargo.lock create mode 100644 wg-password/Cargo.toml create mode 100644 wg-password/PASSWORD.md create mode 100644 wg-password/src/main.rs diff --git a/.dockerignore b/.dockerignore index ca447caf..ef9f460e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,3 @@ -/src/node_modules \ No newline at end of file +/src/node_modules +/wg-password/target +/wg-password/index.js \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index ca427af2..276fec93 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,12 @@ +# Build wg-password binary using Rust on Alpine +FROM rust:1.79.0-alpine AS build_password_binary + +WORKDIR /wg-password +COPY wg-password . + +# Build the Rust project +RUN cargo build --release + # As a workaround we have to build on nodejs 18 # nodejs 20 hangs on build with armv6/armv7 FROM docker.io/library/node:18-alpine AS build_node_modules @@ -26,6 +35,9 @@ COPY --from=build_node_modules /app /app # than what runs inside of docker. COPY --from=build_node_modules /node_modules /node_modules +# Copy the compiled password binary from the build stage to /bin/ +COPY --from=build_password_binary /wg-password/target/release/wgpw /bin/ + # Install Linux packages RUN apk add --no-cache \ dpkg \ diff --git a/README.md b/README.md index 81d531a7..f805100d 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ To automatically install & run wg-easy, simply run: > 💡 Replace `YOUR_SERVER_IP` with your WAN IP, or a Dynamic DNS hostname. > -> 💡 Replace `YOUR_ADMIN_PASSWORD_HASH` with a bcrypt password hash to log in on the Web UI. See How_to_generate_an_bcrypt_hash.md for know how generate the hash. +> 💡 Replace `YOUR_ADMIN_PASSWORD_HASH` with a bcrypt password hash to log in on the Web UI. See [PASSWORD.md](./wg-password/PASSWORD.md) for know how generate the hash. The Web UI will now be available on `http://0.0.0.0:51821`. diff --git a/src/config.js b/src/config.js index 40b70ddf..ac4b407a 100644 --- a/src/config.js +++ b/src/config.js @@ -5,7 +5,6 @@ const { release } = require('./package.json'); module.exports.RELEASE = release; module.exports.PORT = process.env.PORT || '51821'; module.exports.WEBUI_HOST = process.env.WEBUI_HOST || '0.0.0.0'; -module.exports.PASSWORD = process.env.PASSWORD; module.exports.PASSWORD_HASH = process.env.PASSWORD_HASH; module.exports.WG_PATH = process.env.WG_PATH || '/etc/wireguard/'; module.exports.WG_DEVICE = process.env.WG_DEVICE || 'eth0'; diff --git a/src/lib/Server.js b/src/lib/Server.js index d995bb69..7f06da50 100644 --- a/src/lib/Server.js +++ b/src/lib/Server.js @@ -28,22 +28,18 @@ const { PORT, WEBUI_HOST, RELEASE, - PASSWORD, PASSWORD_HASH, LANG, UI_TRAFFIC_STATS, UI_CHART_TYPE, } = require('../config'); -const requiresPassword = !!PASSWORD || !!PASSWORD_HASH; +const requiresPassword = !!PASSWORD_HASH; /** * Checks if `password` matches the PASSWORD_HASH. * - * For backward compatibility it also allows `password` to match the clear text PASSWORD, - * but only if no PASSWORD_HASH is provided. - * - * If both enviornment variables are not set, the password is always invalid. + * If environment variable is not set, the password is always invalid. * * @param {string} password String to test * @returns {boolean} true if matching environment, otherwise false @@ -56,9 +52,6 @@ const isPasswordValid = (password) => { if (PASSWORD_HASH) { return bcrypt.compareSync(password, PASSWORD_HASH); } - if (PASSWORD) { - return password === PASSWORD; - } return false; }; diff --git a/wg-password/.gitignore b/wg-password/.gitignore new file mode 100644 index 00000000..9b9783d9 --- /dev/null +++ b/wg-password/.gitignore @@ -0,0 +1,2 @@ +target +index.mjs \ No newline at end of file diff --git a/wg-password/Cargo.lock b/wg-password/Cargo.lock new file mode 100644 index 00000000..5adbf6bf --- /dev/null +++ b/wg-password/Cargo.lock @@ -0,0 +1,357 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "assert_cmd" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bcrypt" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7" +dependencies = [ + "base64", + "blowfish", + "getrandom", + "subtle", + "zeroize", +] + +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "predicates" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +dependencies = [ + "anstyle", + "difflib", + "float-cmp", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" + +[[package]] +name = "predicates-tree" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wg-password" +version = "0.1.1" +dependencies = [ + "assert_cmd", + "bcrypt", + "predicates", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/wg-password/Cargo.toml b/wg-password/Cargo.toml new file mode 100644 index 00000000..8f4860c0 --- /dev/null +++ b/wg-password/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "wg-password" +version = "0.1.1" +authors = ["tetuaoro <65575727+tetuaoro@users.noreply.github.com>"] +description = "A binary to create bcrypt password hashes for wg-easy, enhancing security." +edition = "2021" + +[dependencies] +bcrypt = "0.15.1" + +[dev-dependencies] +assert_cmd = "2.0" +predicates = "3.0" + +[[bin]] +name = "wgpw" +path = "src/main.rs" diff --git a/wg-password/PASSWORD.md b/wg-password/PASSWORD.md new file mode 100644 index 00000000..1171c036 --- /dev/null +++ b/wg-password/PASSWORD.md @@ -0,0 +1,25 @@ +# wg-password + +`wg-password` is a Rust binary that generates bcrypt password hashes for use with `wg-easy`, enhancing security by requiring passwords. + +## Features + +- Generate bcrypt password hashes. +- Easily integrate with `wg-easy` to enforce password requirements. + +## Usage with Docker + +To generate a bcrypt password hash using Docker, run the following command: + +```sh +docker run ghcr.io/wg-easy/wg-easy wgpw YOUR_PASSWORD +PASSWORD_HASH='$2b$12$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW' // litteraly YOUR_PASSWORD +``` + +## Important + +Make sure to enclose your password in single quotes when you run a linux host and *don't use double* `$`. [See](../How_to_generate_an_bcrypt_hash.md#generating-bcrypt-hash-from-an-script-file). + +## LICENSE + +[wg-easy license](../LICENSE) \ No newline at end of file diff --git a/wg-password/src/main.rs b/wg-password/src/main.rs new file mode 100644 index 00000000..3dc1df55 --- /dev/null +++ b/wg-password/src/main.rs @@ -0,0 +1,39 @@ +fn main() { + let args = std::env::args(); + let collect = args.collect::>(); + match collect.get(1) { + None => panic!("Your password was missing !"), + Some(password) => match bcrypt::hash(password, bcrypt::DEFAULT_COST) { + Err(err) => eprintln!("{}", err.to_string()), + Ok(hash) => println!("PASSWORD_HASH='{hash}'"), + }, + } +} + +#[cfg(test)] +mod test { + use assert_cmd::Command; + use predicates::prelude::*; + + #[test] + fn test_missing_password() { + // Test when no password is provided + let mut cmd = Command::cargo_bin("wgpw").unwrap(); + cmd.assert() + .failure() + .stderr(predicate::str::contains("Your password was missing !")); + } + + #[test] + fn test_generate_password() { + // Test with a valid password + let mut cmd = Command::cargo_bin("wgpw").unwrap(); + cmd.arg("my_password") + .assert() + .success() + .stdout(predicate::str::contains("PASSWORD_HASH='")); + } + + // fn test_invalid_password() { + // } +} From 8bfcb5d502bb8a0681eda7c291134150dc76c3d7 Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Fri, 12 Jul 2024 22:39:26 +0200 Subject: [PATCH 2/7] fix: try fix git action docker build --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 276fec93..790da754 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build wg-password binary using Rust on Alpine -FROM rust:1.79.0-alpine AS build_password_binary +FROM docker.io/library/rust:1.79.0-alpine AS build_password_binary WORKDIR /wg-password COPY wg-password . From cc5d45b83397dbf0f814567bfc62c3f63998ab29 Mon Sep 17 00:00:00 2001 From: Philip H <47042125+pheiduck@users.noreply.github.com> Date: Sun, 14 Jul 2024 16:43:53 +0200 Subject: [PATCH 3/7] Dockerfile: use alpine-base image and install required build packages --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 790da754..48a22d08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,13 @@ # Build wg-password binary using Rust on Alpine -FROM docker.io/library/rust:1.79.0-alpine AS build_password_binary +FROM docker.io/library/alpine AS build_password_binary WORKDIR /wg-password COPY wg-password . # Build the Rust project +RUN apk add --no-cache \ + rust \ + cargo RUN cargo build --release # As a workaround we have to build on nodejs 18 From 883ca34182f021ea99455e2ed6fd8218e9228e57 Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Sun, 14 Jul 2024 17:13:27 +0200 Subject: [PATCH 4/7] rewrite in js --- .dockerignore | 3 +- Dockerfile | 25 +-- wg-password/.gitignore | 4 +- wg-password/Cargo.lock | 357 --------------------------------------- wg-password/Cargo.toml | 17 -- wg-password/PASSWORD.md | 2 +- wg-password/index.mjs | 49 ++++++ wg-password/package.json | 13 ++ wg-password/src/main.rs | 39 ----- wg-password/wgpw.sh | 6 + 10 files changed, 85 insertions(+), 430 deletions(-) delete mode 100644 wg-password/Cargo.lock delete mode 100644 wg-password/Cargo.toml create mode 100644 wg-password/index.mjs create mode 100644 wg-password/package.json delete mode 100644 wg-password/src/main.rs create mode 100755 wg-password/wgpw.sh diff --git a/.dockerignore b/.dockerignore index ef9f460e..ffa1787a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,2 @@ /src/node_modules -/wg-password/target -/wg-password/index.js \ No newline at end of file +/wg-password/node_modules \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 790da754..54c06a6b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,3 @@ -# Build wg-password binary using Rust on Alpine -FROM docker.io/library/rust:1.79.0-alpine AS build_password_binary - -WORKDIR /wg-password -COPY wg-password . - -# Build the Rust project -RUN cargo build --release - # As a workaround we have to build on nodejs 18 # nodejs 20 hangs on build with armv6/armv7 FROM docker.io/library/node:18-alpine AS build_node_modules @@ -20,6 +11,12 @@ WORKDIR /app RUN npm ci --omit=dev &&\ mv node_modules /node_modules +# Copy script wg-password +COPY wg-password /wgpw +WORKDIR /wgpw +RUN npm i --omit=dev &&\ + mv node_modules /node_modules_wg + # Copy build result to a new image. # This saves a lot of disk space. FROM docker.io/library/node:20-alpine @@ -35,8 +32,12 @@ COPY --from=build_node_modules /app /app # than what runs inside of docker. COPY --from=build_node_modules /node_modules /node_modules -# Copy the compiled password binary from the build stage to /bin/ -COPY --from=build_password_binary /wg-password/target/release/wgpw /bin/ +# Copy the needed wg-password scripts +COPY --from=build_node_modules /node_modules_wg /node_modules_wg +COPY --from=build_node_modules /wgpw/index.mjs /wgpw/index.mjs +COPY --from=build_node_modules /wgpw/wgpw.sh /bin/wgpw + +RUN chmod +x /bin/wgpw # Install Linux packages RUN apk add --no-cache \ @@ -54,4 +55,4 @@ ENV DEBUG=Server,WireGuard # Run Web UI WORKDIR /app -CMD ["/usr/bin/dumb-init", "node", "server.js"] +CMD ["/usr/bin/dumb-init", "node", "server.js"] \ No newline at end of file diff --git a/wg-password/.gitignore b/wg-password/.gitignore index 9b9783d9..e83bf3ec 100644 --- a/wg-password/.gitignore +++ b/wg-password/.gitignore @@ -1,2 +1,2 @@ -target -index.mjs \ No newline at end of file +pnpm-lock.yaml +node_modules \ No newline at end of file diff --git a/wg-password/Cargo.lock b/wg-password/Cargo.lock deleted file mode 100644 index 5adbf6bf..00000000 --- a/wg-password/Cargo.lock +++ /dev/null @@ -1,357 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstyle" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" - -[[package]] -name = "assert_cmd" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8" -dependencies = [ - "anstyle", - "bstr", - "doc-comment", - "predicates", - "predicates-core", - "predicates-tree", - "wait-timeout", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bcrypt" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7" -dependencies = [ - "base64", - "blowfish", - "getrandom", - "subtle", - "zeroize", -] - -[[package]] -name = "blowfish" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" -dependencies = [ - "byteorder", - "cipher", -] - -[[package]] -name = "bstr" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" -dependencies = [ - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "difflib" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" - -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -dependencies = [ - "num-traits", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "predicates" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" -dependencies = [ - "anstyle", - "difflib", - "float-cmp", - "normalize-line-endings", - "predicates-core", - "regex", -] - -[[package]] -name = "predicates-core" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" - -[[package]] -name = "predicates-tree" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" -dependencies = [ - "predicates-core", - "termtree", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex" -version = "1.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "serde" -version = "1.0.204" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.204" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termtree" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wg-password" -version = "0.1.1" -dependencies = [ - "assert_cmd", - "bcrypt", - "predicates", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/wg-password/Cargo.toml b/wg-password/Cargo.toml deleted file mode 100644 index 8f4860c0..00000000 --- a/wg-password/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "wg-password" -version = "0.1.1" -authors = ["tetuaoro <65575727+tetuaoro@users.noreply.github.com>"] -description = "A binary to create bcrypt password hashes for wg-easy, enhancing security." -edition = "2021" - -[dependencies] -bcrypt = "0.15.1" - -[dev-dependencies] -assert_cmd = "2.0" -predicates = "3.0" - -[[bin]] -name = "wgpw" -path = "src/main.rs" diff --git a/wg-password/PASSWORD.md b/wg-password/PASSWORD.md index 1171c036..280a2b0d 100644 --- a/wg-password/PASSWORD.md +++ b/wg-password/PASSWORD.md @@ -1,6 +1,6 @@ # wg-password -`wg-password` is a Rust binary that generates bcrypt password hashes for use with `wg-easy`, enhancing security by requiring passwords. +`wg-password` is a script that generates bcrypt password hashes for use with `wg-easy`, enhancing security by requiring passwords. ## Features diff --git a/wg-password/index.mjs b/wg-password/index.mjs new file mode 100644 index 00000000..59cc419d --- /dev/null +++ b/wg-password/index.mjs @@ -0,0 +1,49 @@ +// Import needed libraries +import bcrypt from 'bcryptjs'; + +// Function to generate hash +const generateHash = async (password) => { + try { + const salt = await bcrypt.genSalt(12); + const hash = await bcrypt.hash(password, salt); + console.log(`PASSWORD_HASH='${hash}'`); + } catch (error) { + throw new Error(`Failed to generate hash : ${error}`); + } +} + +// Function to compare password with hash +const comparePassword = async (password, hash) => { + try { + const match = await bcrypt.compare(password, hash); + if (match) { + console.log('Password matches the hash !'); + } else { + console.log('Password does not match the hash.'); + } + } catch (error) { + throw new Error(`Failed to compare password and hash : ${error}`); + } +} + +(async () => { + try { + // Retrieve command line arguments + const args = process.argv.slice(2); // Ignore the first two arguments + if (args.length > 2) { + throw new Error('Usage : wgpw YOUR_PASSWORD [HASH]'); + } + + const [password, hash] = args; + if (password && hash) { + await comparePassword(password, hash); + } else if (password) { + await generateHash(password); + } + + process.exit(0); + } catch (error) { + console.error(error); + process.exit(1); + } +})(); diff --git a/wg-password/package.json b/wg-password/package.json new file mode 100644 index 00000000..ab33138b --- /dev/null +++ b/wg-password/package.json @@ -0,0 +1,13 @@ +{ + "name": "wg-password", + "version": "1.0.1", + "description": "A binary to create bcrypt password hashes for wg-easy, enhancing security.", + "main": "index.mjs", + "author": "tetuaoro <65575727+tetuaoro@users.noreply.github.com>", + "dependencies": { + "bcryptjs": "^2.4.3" + }, + "engines": { + "node": ">=18" + } +} \ No newline at end of file diff --git a/wg-password/src/main.rs b/wg-password/src/main.rs deleted file mode 100644 index 3dc1df55..00000000 --- a/wg-password/src/main.rs +++ /dev/null @@ -1,39 +0,0 @@ -fn main() { - let args = std::env::args(); - let collect = args.collect::>(); - match collect.get(1) { - None => panic!("Your password was missing !"), - Some(password) => match bcrypt::hash(password, bcrypt::DEFAULT_COST) { - Err(err) => eprintln!("{}", err.to_string()), - Ok(hash) => println!("PASSWORD_HASH='{hash}'"), - }, - } -} - -#[cfg(test)] -mod test { - use assert_cmd::Command; - use predicates::prelude::*; - - #[test] - fn test_missing_password() { - // Test when no password is provided - let mut cmd = Command::cargo_bin("wgpw").unwrap(); - cmd.assert() - .failure() - .stderr(predicate::str::contains("Your password was missing !")); - } - - #[test] - fn test_generate_password() { - // Test with a valid password - let mut cmd = Command::cargo_bin("wgpw").unwrap(); - cmd.arg("my_password") - .assert() - .success() - .stdout(predicate::str::contains("PASSWORD_HASH='")); - } - - // fn test_invalid_password() { - // } -} diff --git a/wg-password/wgpw.sh b/wg-password/wgpw.sh new file mode 100755 index 00000000..abcfec53 --- /dev/null +++ b/wg-password/wgpw.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# This script is intended to be run only inside a docker container, not on the development host machine +set -e +# proxy command +export NODE_PATH="/node_modules_wg" +node /wgpw/index.mjs "$@" \ No newline at end of file From a9c798deda2628acf0c786acd6942feff9f33fb3 Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Sun, 14 Jul 2024 17:58:34 +0200 Subject: [PATCH 5/7] move files --- Dockerfile | 11 +---------- wg-password/index.mjs => src/wgpw.mjs | 0 {wg-password => src}/wgpw.sh | 3 +-- wg-password/.gitignore | 2 -- wg-password/PASSWORD.md | 25 ------------------------- wg-password/package.json | 13 ------------- 6 files changed, 2 insertions(+), 52 deletions(-) rename wg-password/index.mjs => src/wgpw.mjs (100%) rename {wg-password => src}/wgpw.sh (69%) delete mode 100644 wg-password/.gitignore delete mode 100644 wg-password/PASSWORD.md delete mode 100644 wg-password/package.json diff --git a/Dockerfile b/Dockerfile index 54c06a6b..c9238f39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,12 +11,6 @@ WORKDIR /app RUN npm ci --omit=dev &&\ mv node_modules /node_modules -# Copy script wg-password -COPY wg-password /wgpw -WORKDIR /wgpw -RUN npm i --omit=dev &&\ - mv node_modules /node_modules_wg - # Copy build result to a new image. # This saves a lot of disk space. FROM docker.io/library/node:20-alpine @@ -33,10 +27,7 @@ COPY --from=build_node_modules /app /app COPY --from=build_node_modules /node_modules /node_modules # Copy the needed wg-password scripts -COPY --from=build_node_modules /node_modules_wg /node_modules_wg -COPY --from=build_node_modules /wgpw/index.mjs /wgpw/index.mjs -COPY --from=build_node_modules /wgpw/wgpw.sh /bin/wgpw - +COPY --from=build_node_modules /app/wgpw.sh /bin/wgpw RUN chmod +x /bin/wgpw # Install Linux packages diff --git a/wg-password/index.mjs b/src/wgpw.mjs similarity index 100% rename from wg-password/index.mjs rename to src/wgpw.mjs diff --git a/wg-password/wgpw.sh b/src/wgpw.sh similarity index 69% rename from wg-password/wgpw.sh rename to src/wgpw.sh index abcfec53..aac6afa1 100755 --- a/wg-password/wgpw.sh +++ b/src/wgpw.sh @@ -2,5 +2,4 @@ # This script is intended to be run only inside a docker container, not on the development host machine set -e # proxy command -export NODE_PATH="/node_modules_wg" -node /wgpw/index.mjs "$@" \ No newline at end of file +node /app/wgpw.mjs "$@" \ No newline at end of file diff --git a/wg-password/.gitignore b/wg-password/.gitignore deleted file mode 100644 index e83bf3ec..00000000 --- a/wg-password/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -pnpm-lock.yaml -node_modules \ No newline at end of file diff --git a/wg-password/PASSWORD.md b/wg-password/PASSWORD.md deleted file mode 100644 index 280a2b0d..00000000 --- a/wg-password/PASSWORD.md +++ /dev/null @@ -1,25 +0,0 @@ -# wg-password - -`wg-password` is a script that generates bcrypt password hashes for use with `wg-easy`, enhancing security by requiring passwords. - -## Features - -- Generate bcrypt password hashes. -- Easily integrate with `wg-easy` to enforce password requirements. - -## Usage with Docker - -To generate a bcrypt password hash using Docker, run the following command: - -```sh -docker run ghcr.io/wg-easy/wg-easy wgpw YOUR_PASSWORD -PASSWORD_HASH='$2b$12$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW' // litteraly YOUR_PASSWORD -``` - -## Important - -Make sure to enclose your password in single quotes when you run a linux host and *don't use double* `$`. [See](../How_to_generate_an_bcrypt_hash.md#generating-bcrypt-hash-from-an-script-file). - -## LICENSE - -[wg-easy license](../LICENSE) \ No newline at end of file diff --git a/wg-password/package.json b/wg-password/package.json deleted file mode 100644 index ab33138b..00000000 --- a/wg-password/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "wg-password", - "version": "1.0.1", - "description": "A binary to create bcrypt password hashes for wg-easy, enhancing security.", - "main": "index.mjs", - "author": "tetuaoro <65575727+tetuaoro@users.noreply.github.com>", - "dependencies": { - "bcryptjs": "^2.4.3" - }, - "engines": { - "node": ">=18" - } -} \ No newline at end of file From f5d93f6c5a92771aae47e6ea0e5f37fc51784004 Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Sun, 14 Jul 2024 18:09:13 +0200 Subject: [PATCH 6/7] fix: lint errors --- src/wgpw.mjs | 75 ++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/src/wgpw.mjs b/src/wgpw.mjs index 59cc419d..4062a73e 100644 --- a/src/wgpw.mjs +++ b/src/wgpw.mjs @@ -1,49 +1,54 @@ +'use strict'; + // Import needed libraries import bcrypt from 'bcryptjs'; // Function to generate hash const generateHash = async (password) => { - try { - const salt = await bcrypt.genSalt(12); - const hash = await bcrypt.hash(password, salt); - console.log(`PASSWORD_HASH='${hash}'`); - } catch (error) { - throw new Error(`Failed to generate hash : ${error}`); - } -} + try { + const salt = await bcrypt.genSalt(12); + const hash = await bcrypt.hash(password, salt); + // eslint-disable-next-line no-console + console.log(`PASSWORD_HASH='${hash}'`); + } catch (error) { + throw new Error(`Failed to generate hash : ${error}`); + } +}; // Function to compare password with hash const comparePassword = async (password, hash) => { - try { - const match = await bcrypt.compare(password, hash); - if (match) { - console.log('Password matches the hash !'); - } else { - console.log('Password does not match the hash.'); - } - } catch (error) { - throw new Error(`Failed to compare password and hash : ${error}`); + try { + const match = await bcrypt.compare(password, hash); + if (match) { + // eslint-disable-next-line no-console + console.log('Password matches the hash !'); + } else { + // eslint-disable-next-line no-console + console.log('Password does not match the hash.'); } -} + } catch (error) { + throw new Error(`Failed to compare password and hash : ${error}`); + } +}; (async () => { - try { - // Retrieve command line arguments - const args = process.argv.slice(2); // Ignore the first two arguments - if (args.length > 2) { - throw new Error('Usage : wgpw YOUR_PASSWORD [HASH]'); - } - - const [password, hash] = args; - if (password && hash) { - await comparePassword(password, hash); - } else if (password) { - await generateHash(password); - } + try { + // Retrieve command line arguments + const args = process.argv.slice(2); // Ignore the first two arguments + if (args.length > 2) { + throw new Error('Usage : wgpw YOUR_PASSWORD [HASH]'); + } - process.exit(0); - } catch (error) { - console.error(error); - process.exit(1); + const [password, hash] = args; + if (password && hash) { + await comparePassword(password, hash); + } else if (password) { + await generateHash(password); } + } catch (error) { + // eslint-disable-next-line no-console + console.error(error); + // eslint-disable-next-line no-process-exit + process.exit(1); + } })(); From 53dad56bb61d00a196d041238f874eb20ffc8ca1 Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Sun, 14 Jul 2024 18:19:52 +0200 Subject: [PATCH 7/7] some corrections --- .dockerignore | 3 +- How_to_generate_an_bcrypt_hash.md | 118 ++++++------------------------ README.md | 2 +- 3 files changed, 23 insertions(+), 100 deletions(-) diff --git a/.dockerignore b/.dockerignore index ffa1787a..ca447caf 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1 @@ -/src/node_modules -/wg-password/node_modules \ No newline at end of file +/src/node_modules \ No newline at end of file diff --git a/How_to_generate_an_bcrypt_hash.md b/How_to_generate_an_bcrypt_hash.md index 46cb2275..ca3e5ee8 100644 --- a/How_to_generate_an_bcrypt_hash.md +++ b/How_to_generate_an_bcrypt_hash.md @@ -1,110 +1,34 @@ - -# How to generate bcrypt hash +# wg-password -## Prerequisites -- Python 3 -- bcrypt library +`wg-password` (wgpg) is a script that generates bcrypt password hashes for use with `wg-easy`, enhancing security by requiring passwords. -## Prerequisites Installation -### Windows -Download and install Python 3 from [official website](https://www.python.org/downloads/). -Check "Add python.exe to PATH" before running "Install Now". +## Features -Open Command Prompt (win + r, type "cmd" and press enter) and run the following command to install bcrypt library: -```bash -pip install bcrypt -``` +- Generate bcrypt password hashes. +- Easily integrate with `wg-easy` to enforce password requirements. -### Debian based distributions -```bash -sudo apt-get update -sudo apt-get install python3 python3-pip -# If you use have install python using apt -sudo apt-get install python3-bcrypt -# If don't install python using apt -pip3 install bcrypt -# If you got externally-managed-environment error -pip3 install bcrypt --break-system-packages -``` +## Usage with Docker -### Fedora based distributions -```bash -sudo dnf update -sudo dnf install python3 python3-pip -# If you use have install python using dnf -sudo dnf install python3-bcrypt -# If don't install python using dnf -pip3 install bcrypt -# If you got externally-managed-environment error -pip3 install bcrypt --break-system-packages -``` +To generate a bcrypt password hash using Docker, run the following command: -### Arch Linux based distributions -```bash -sudo pacman -Syy -sudo pacman -S python python-pip -# If you use have install python using pacman -sudo pacman -S python-bcrypt -# If don't install python using pacman -pip3 install bcrypt -# If you got externally-managed-environment error -pip3 install bcrypt --break-system-packages +```sh +docker run ghcr.io/wg-easy/wg-easy wgpw YOUR_PASSWORD +PASSWORD_HASH='$2b$12$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW' // litteraly YOUR_PASSWORD ``` -### macOS -```bash -brew install bcrypt -# If don't install bcrypt using homebrew -pip3 install bcrypt -# If you got externally-managed-environment error -pip3 install bcrypt --break-system-packages -``` +## Important -## Generating bcrypt hash from the command line -You can use the following one-liner command to generate a bcrypt hash directly in the cmd/ terminal: -```bash -python3 -c "import bcrypt; password = b'your_password_here'; assert len(password) < 72, 'Password must be less than 72 bytes due to bcrypt limitation'; hashed = bcrypt.hashpw(password, bcrypt.gensalt()); print(f'The hashed password is: {hashed.decode()}'); docker_interpolation = hashed.decode().replace('$', '$'*2); print(f'The hashed password for a Docker env is: {docker_interpolation}')" # or python if you run this on Windows. CHANGE your_password_here BY YOUR PASSWORD -``` -Please change ``your_password_here`` in the line by your own password. +Make sure to enclose your password in single quotes when you run a linux host. -## Generating bcrypt hash from an script file -### Do not name the file `bcrypt.py` as it will cause an error. -Create a python file with the following content: -```python -import bcrypt - -# Initial password -password = b"your_password_here" # DO NOT REMOVE THE b - -# Assert that the password is under 72 bytes -assert len(password) < 72, "Password must be less than 72 bytes due to bcrypt limitation" - -# Generate a salt and hash the password -hashed = bcrypt.hashpw(password, bcrypt.gensalt()) - -# Print the hashed password -print(f'The hashed password is: {hashed.decode()}') - -# Prepare the hashed password for Docker environment variables -docker_interpolation = hashed.decode().replace("$", "$$") -print(f'The hashed password for a Docker env is: {docker_interpolation}') +```bash +$ echo $2b$12$coPqCsPtcF +b2 +$ echo "$2b$12$coPqCsPtcF" +b2 +$ echo '$2b$12$coPqCsPtcF' +$2b$12$coPqCsPtcF ``` -Replace `your_password_here` with the password you want to hash. - -Run the python file and you will get the hashed password. - -## Get the right hash -Copy the 2nd line of the output (after the : ) and use it as your hashed password. +## LICENSE -__Exemple__ -If the output is: -```txt -The hashed password is: $2b$12$NRiL4Kw4dKid.ix2WvZltOmaQBZjoX30shjHJXRVdEGshAxYWXXMe -The hashed password for an docker env is: $$2b$$12$$NRiL4Kw4dKid.ix2WvZltOmaQBZjoX30shjHJXRVdEGshAxYWXXMe -``` - -The docker line ``PASSWORD_HASH`` will be: -```txt -PASSWORD_HASH=$$2b$$12$$NRiL4Kw4dKid.ix2WvZltOmaQBZjoX30shjHJXRVdEGshAxYWXXMe -``` +[wg-easy license](./LICENSE) \ No newline at end of file diff --git a/README.md b/README.md index f805100d..e559b99b 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ To automatically install & run wg-easy, simply run: > 💡 Replace `YOUR_SERVER_IP` with your WAN IP, or a Dynamic DNS hostname. > -> 💡 Replace `YOUR_ADMIN_PASSWORD_HASH` with a bcrypt password hash to log in on the Web UI. See [PASSWORD.md](./wg-password/PASSWORD.md) for know how generate the hash. +> 💡 Replace `YOUR_ADMIN_PASSWORD_HASH` with a bcrypt password hash to log in on the Web UI. See [How_to_generate_an_bcrypt_hash.md](./How_to_generate_an_bcrypt_hash.md) for know how generate the hash. The Web UI will now be available on `http://0.0.0.0:51821`.