diff --git a/assets/healtcheck b/assets/healtcheck new file mode 100644 index 0000000..2479466 --- /dev/null +++ b/assets/healtcheck @@ -0,0 +1,12 @@ +#/bin/sh + +if [ ! -d /config ]; then + exit 1 +fi + +if [ ! -f /config/psiphon.config ]; then + exit 1 +else + HTTP_PORT=$(sed -n -E 's/.*"LocalHttpProxyPort"[[:space:]]*:[[:space:]]*([0-9]+).*/\1/p' /config/psiphon.config) + netstat -ltn | grep ${HTTP_PORT} || exit 1 +fi diff --git a/psiphon.config b/assets/psiphon.config similarity index 99% rename from psiphon.config rename to assets/psiphon.config index af1a98a..4e2adde 100644 --- a/psiphon.config +++ b/assets/psiphon.config @@ -1,6 +1,7 @@ { "DataRootDirectory": "/config/", "DeviceRegion": "IN", + "EgressRegion": "SG", "MigrateDataStoreDirectory": "/config", "ListenInterface": "any", "LocalHttpProxyPort": 8080, diff --git a/assets/start-psiphon b/assets/start-psiphon new file mode 100644 index 0000000..669709d --- /dev/null +++ b/assets/start-psiphon @@ -0,0 +1,46 @@ +#!/bin/sh + +if [ ! -d /config ]; then + echo "/config directory not mounted, exiting..." + exit 1 +fi + +if [ ! -f /config/psiphon.config ]; then + cp /etc/psiphon/psiphon.config /config/psiphon.config + if [ -n "${HTTP_PORT}" ]; then + sed -i -E 's/"LocalHttpProxyPort"[[:space:]]*:[[:space:]]*[0-9]+/"LocalHttpProxyPort": '${HTTP_PORT}'/' /config/psiphon.config + fi + if [ -n "${SOCKS_PORT}" ]; then + sed -i -E 's/"LocalSocksProxyPort"[[:space:]]*:[[:space:]]*[0-9]+/"LocalSocksProxyPort": '${SOCKS_PORT}'/' /config/psiphon.config + fi + if [ -n "${DEVICE_REGION}" ]; then + sed -i -E 's/"DeviceRegion"[[:space:]]*:[[:space:]]*"[^"]*"/"DeviceRegion": "'${DEVICE_REGION}'"/' /config/psiphon.config + fi + if [ -n "${EGRESS_REGION}" ]; then + sed -i -E 's/"EgressRegion"[[:space:]]*:[[:space:]]*"[^"]*"/"EgressRegion": "'${EGRESS_REGION}'"/' /config/psiphon.config + fi +fi + +id psiphon > /dev/null 2>&1 +if [ $? -ne 0 ]; then + adduser -DH psiphon psiphon +fi + +UID=$(id -u psiphon) +GID=$(id -g psiphon) + +PUID=${PUID:-${UID}} +PGID=${PGID:-${GID}} + +if [ "${PUID}" != "${UID}" ] || [ "${PGID}" != "${GID}" ]; then + deluser psiphon >/dev/null 2>&1 || true + delgroup psiphon >/dev/null 2>&1 || true + addgroup -g ${PGID} psiphon + adduser -DH -u ${PUID} -G psiphon psiphon +fi + +chown -R psiphon:psiphon /config + +su -s /bin/sh psiphon < /run/s6-linux-init-container-results/exitcode diff --git a/base/etc/services.d/psiphon/run b/base/etc/services.d/psiphon/run deleted file mode 100755 index c262ae8..0000000 --- a/base/etc/services.d/psiphon/run +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/with-contenv sh - -[[ ! -f ${DEF_CONFIG}/psiphon.config ]] && cp ${DEF_DEFAULTS}/psiphon.config ${DEF_CONFIG}/ - -chown -R ${DEF_USER}:${DEF_USER} ${DEF_CONFIG} - -exec s6-setuidgid ${DEF_USER} ${DEF_APP}/psiphon -config ${DEF_CONFIG}/psiphon.config diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..dc54b80 --- /dev/null +++ b/build.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +set -euo pipefail +IFS=$'\n\t' + +GO=${GO:-go} +PSIPHON_VERSION="" +TARGETS="" + +function help_message() { + echo "Usage: $0 [OPTIONS] " + echo "Options:" + echo " --targets Comma-separated list of target platforms (default: current platform)" + echo " --version Psiphon version to build (default: latest)" + exit ${1:-1} +} + +while [[ $# -gt 0 ]]; do + case $1 in + --help|-h) + help_message 0 + ;; + --targets=*) + TARGETS="${1#*=}" + shift + ;; + -t | --targets) + TARGETS="${2}" + shift 2 + ;; + --version=*) + PSIPHON_VERSION="${1#*=}" + shift + ;; + -v | --version) + PSIPHON_VERSION="${2}" + shift 2 + ;; + *) + echo "Unknown option: $1" + help_message + ;; + esac +done + +source ./lastest_version.sh + +if [[ -z "${PSIPHON_VERSION}" ]]; then + PSIPHON_VERSION=$(get_latest_version) +else + if ! validate_version_format "$PSIPHON_VERSION"; then + echo "Invalid Psiphon version format. Please use 'X.Y.Z' or 'vX.Y.Z' format." + exit 1 + fi +fi + +PSIPHON_VERSION=$(normalize_version "$PSIPHON_VERSION") +ALL_TARGETS="linux/amd64,linux/386,linux/arm64,linux/arm/v7,linux/arm/v6,windows/amd64,windows/386,darwin/amd64,darwin/arm64" +CURRENT_TARGET="$(go env GOOS)/$(go env GOARCH)" +TARGETS=${TARGETS:-"current"} + +if [[ "${TARGETS}" == "current" ]]; then + TARGETS="${CURRENT_TARGET}" +elif [[ "${TARGETS}" == "all" ]]; then + TARGETS="${ALL_TARGETS}" +fi + +TARGETS=${TARGETS//,/ } + +BUILD_DIR=$(pwd)/tmp_build_$$ +rm -rf "${BUILD_DIR}" +mkdir -p "${BUILD_DIR}" +trap 'rm -rf "${BUILD_DIR}"' EXIT + +BIN_DIR="$(pwd)/dist" +rm -rf "${BIN_DIR}" +mkdir -p "${BIN_DIR}" + +curl -sL https://github.com/Psiphon-Labs/psiphon-tunnel-core/archive/refs/tags/${PSIPHON_VERSION}.tar.gz | tar xz --strip-components=1 -C "${BUILD_DIR}" +pushd "${BUILD_DIR}/ConsoleClient" > /dev/null + +for PLATFORM in ${TARGETS} +do + IFS='/' read -r OS ARCH VARIANT <<< "${PLATFORM}" + GOEXT="" + if [[ "${OS}" == "windows" ]]; then + GOEXT=".exe" + fi + + GOARM_ENV="" + if [[ -n "${VARIANT}" ]]; then + GOARM_ENV="GOARM=${VARIANT#v}" + fi + + CGO_ENABLED=0 GOOS=${OS} GOARCH=${ARCH} ${GOARM_ENV} ${GO} build -a -tags netgo -ldflags "-s -w -extldflags '-static'" -o "${BIN_DIR}/psiphon_${PLATFORM//\//_}${GOEXT}" +done + +popd > /dev/null diff --git a/latest_version.sh b/latest_version.sh new file mode 100644 index 0000000..7f2ab66 --- /dev/null +++ b/latest_version.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -euo pipefail +IFS=$'\n\t' + +# This file can only be sourced, not executed directly. +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + echo "This script is intended to be sourced, not executed directly." >&2 + exit 1 +fi + +function validate_version_format() { + local v="$1" + [[ "$v" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]] +} + +function get_latest_version() { + local json version + json="$(curl -fsSL https://api.github.com/repos/Psiphon-Labs/psiphon-tunnel-core/releases/latest)" + if command -v jq >/dev/null 2>&1; then + version="$(printf '%s' "$json" | jq -r .tag_name)" + else + version="$(printf '%s' "$json" \ + | grep -m1 '"tag_name":' \ + | sed -E 's/.*"tag_name": ?"([^"]+)".*/\1/')" + fi + + if ! validate_version_format "$version"; then + echo "I tried to get the latest version of Psiphon without jq but it didn't work." >&2 + echo "Please install jq or specify the version manually." >&2 + exit 1 + fi + + printf '%s\n' "$version" +} + +function normalize_version() { + local v="$1" + if [[ "$v" =~ ^v ]]; then + echo "$v" + else + echo "v$v" + fi +} \ No newline at end of file