diff --git a/Dockerfile b/Dockerfile index 725755f..e1c80cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,6 +23,9 @@ RUN sed -i '/blahblah/i\return 0;' config.m4 && \ FROM alpine:3.16 AS asset COPY --from=iconv /iconv/ /asset/usr/ COPY --from=vlmcsd /tmp/vlmcs* /asset/usr/bin/ +RUN apk add php8-fpm && mkdir -p /asset/etc/php8/ && \ + sed -i 's/^;\(pid\)/\1/' /etc/php8/php-fpm.conf && \ + mv /etc/php8/php-fpm.conf /asset/etc/php8/ COPY . /asset/kms-server/ RUN mkdir -p /asset/etc/ && mv /asset/kms-server/nginx/ /asset/etc/ diff --git a/main.php b/main.php index 6c96fbe..4edf872 100644 --- a/main.php +++ b/main.php @@ -9,7 +9,7 @@ require_once './src/Process.php'; $nginx = array( 'name' => 'nginx', 'command' => ['/usr/sbin/nginx'], - 'pidFile' => '/run/nginx/nginx.pid', + 'pidFile' => '/run/nginx.pid', ); $phpFpm = array( diff --git a/nginx/kms.conf b/nginx/kms.conf index 3604bdc..7558a2d 100644 --- a/nginx/kms.conf +++ b/nginx/kms.conf @@ -1,6 +1,15 @@ server { listen 1689; - root /kms-server; + listen [::]:1689 ipv6only=on; + set $kms_dir '/kms-server'; + + location /assets { + root $kms_dir; + } + + location = /json { + alias $kms_dir/assets/kms-keys.json; + } location / { set $query_param $query_string; @@ -10,8 +19,6 @@ server { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param QUERY_STRING $query_param; - fastcgi_param SCRIPT_FILENAME /kms-server/src/Route.php; + fastcgi_param SCRIPT_FILENAME $kms_dir/src/Route.php; } - - location /assets {} } diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 41ac84a..b0cf953 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -1,6 +1,8 @@ user nginx; -worker_processes auto; pcre_jit on; +pid /run/nginx.pid; + +worker_processes auto; include /etc/nginx/modules/*.conf; events { diff --git a/src/Basis.php b/src/Basis.php index a8ba2cb..f105abc 100644 --- a/src/Basis.php +++ b/src/Basis.php @@ -12,20 +12,29 @@ function lenUtf8(string $str): int { // get string length (Chinese -> 2) return strlen(iconv('utf-8', 'gb2312', $str)); } -function isIPv4($ip): bool { +function isIPv4(string $ip): bool { return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); } -function isIPv6($ip): bool { +function isIPv6(string $ip): bool { return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); } -function isDomain($domain): bool { +function isDomain(string $domain): bool { $regex = '/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/'; preg_match($regex, $domain, $match); return count($match) != 0; } +function isHost(string $host): bool { // IPv4 / IPv6 / Domain + return isIPv4($host) or isIPv6($host) or isDomain($host); +} + +function isPort(int $port): bool { + $port = intval($port); + return ($port < 65536 and $port > 0); +} + function getKeys(bool $isWinServer = false): array { // get kms keys asset $keysAsset = json_decode(file_get_contents('../assets/kms-keys.json'), true); return $isWinServer ? array_reverse($keysAsset['win-server']) : $keysAsset['win']; @@ -43,7 +52,7 @@ function getHost(): string { return 'KMS_HOST'; } $host = v6DelBracket($_SERVER['HTTP_HOST']); // try to remove ipv6 bracket - if (isIPv4($host) or isIPv6($host) or isDomain($host)) { // invalid host + if (isHost($host)) { // valid host return $host; } preg_match_all('/(\S+):\d+$/', $host, $match); @@ -51,7 +60,7 @@ function getHost(): string { return 'KMS_HOST'; } $host = v6DelBracket($match[1][0]); // try to remove ipv6 bracket again - return (isIPv4($host) or isIPv6($host) or isDomain($host)) ? $host : 'KMS_HOST'; + return (isHost($host)) ? $host : 'KMS_HOST'; } function officeInfo(): array { // office dir and kms key for different version diff --git a/src/Check.php b/src/Check.php index c3079e1..011f043 100644 --- a/src/Check.php +++ b/src/Check.php @@ -11,7 +11,7 @@ function vlmcsCheck(string $host, int $port = 1688): bool { return count($match[0]) != 0; } -function kmsCheck(): array { +function kmsCheckApi(): array { if (!isset($_GET['host'])) { // missing host param return array( 'success' => false, @@ -35,12 +35,42 @@ function kmsCheck(): array { if (vlmcsCheck($host, $port)) { // KMS server available return array( 'success' => true, + 'available' => true, + 'host' => $host, + 'port' => intval($port), 'message' => 'kms server available' ); } else { // KMS server couldn't reach return array( - 'success' => false, + 'success' => true, + 'available' => false, + 'host' => $host, + 'port' => intval($port), 'message' => 'kms server connect failed' ); } } + +function kmsCheckCli(string $host): void { + $port = 1688; + $host = v6DelBracket($host); // try to remove ipv6 bracket + if (!isIPv4($host) and !isIPv6($host) and !isDomain($host)) { // invalid host + preg_match_all('/(\S+):(\d+)$/', $host, $match); + if (!count($match[1]) or !count($match[2])) { // ${HOST}:${PORT} format not found + echo "Invalid host\n"; + exit; + } + $port = $match[2][0]; + $host = v6DelBracket($match[1][0]); // try to remove ipv6 bracket + if (!isIPv4($host) and !isIPv6($host) and !isDomain($host)) { // still invalid host + echo "Invalid host\n"; + exit; + } + } + if (!isPort($port)) { + echo "Invalid port\n"; + exit; + } + echo "KMS Server: $host ($port) -> "; + echo (vlmcsCheck($host, $port) ? 'available': 'connect failed') . PHP_EOL; +} diff --git a/src/Route.php b/src/Route.php index 6504a40..c0e4787 100644 --- a/src/Route.php +++ b/src/Route.php @@ -34,9 +34,11 @@ if ($url == '/' or $url == '/help') { } else { $isCli ? showKeysCli($kmsKeys, $isGbk) : showKeysHtml($kmsKeys, $caption); // kms keys of windows } -} else if ($url == '/check') { +} else if ($url == '/check' or $url == '/check/') { mimeJson(); - echo json_encode(kmsCheck()); // check kms server + echo json_encode(kmsCheckApi()); // check kms server +} else if (str_starts_with($url, '/check/')) { + kmsCheckCli(substr($url, 7)); // check kms server (split `/check/`) } else { // unknown request if ($isCli) { echo "Illegal Request\n";