diff --git a/Dockerfile b/Dockerfile index 6aa882f..ba57f56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,12 +19,15 @@ RUN sed -i '/blahblah/i\return 0;' config.m4 && phpize && \ RUN strip /tmp/*.so* FROM alpine:3.16 AS asset +RUN apk add php8-fpm +WORKDIR /asset/etc/php8/ +RUN cat /etc/php8/php-fpm.conf | sed 's/^;\(pid\)/\1/' > php-fpm.conf +WORKDIR /asset/etc/php8/php-fpm.d/ +RUN cat /etc/php8/php-fpm.d/www.conf | sed 's?127.0.0.1:9000?/run/php-fpm.sock?' > www.conf && \ + echo -e 'listen.owner = nginx\nlisten.group = nginx' >> www.conf COPY --from=vlmcsd /tmp/vlmcs* /asset/usr/bin/ COPY --from=iconv /tmp/libiconv.so.2 /asset/usr/local/lib/ COPY --from=iconv /tmp/iconv.so /asset/usr/lib/php8/modules/ -RUN apk add php8-fpm -WORKDIR /asset/etc/php8/ -RUN sed -i 's/^;\(pid\)/\1/' /etc/php8/php-fpm.conf && mv /etc/php8/php-fpm.conf ./ COPY ./nginx/ /asset/etc/nginx/ COPY ./ /asset/kms-server/ RUN ln -s /kms-server/kms.php /asset/usr/bin/kms-server diff --git a/kms.php b/kms.php index c76d274..c307f9c 100755 --- a/kms.php +++ b/kms.php @@ -7,72 +7,139 @@ require_once './src/Daemon.php'; require_once './src/Logger.php'; require_once './src/Process.php'; -$nginx = array( +$KMS_PORT = 1688; // kms expose port +$HTTP_PORT = 1689; // http server port + +$NGINX = array( // nginx process 'name' => 'nginx', 'command' => ['/usr/sbin/nginx'], 'pidFile' => '/run/nginx.pid', ); -$phpFpm = array( +$PHP_FPM = array( // php-fpm process 'name' => 'php-fpm8', 'command' => ['/usr/sbin/php-fpm8'], 'pidFile' => '/run/php-fpm8.pid', ); -$vlmcsd = array( +$VLMCSD = array( // vlmcsd process 'name' => 'vlmcsd', 'command' => ['/usr/bin/vlmcsd', '-e', '-p', '/run/vlmcsd.pid'], 'pidFile' => '/run/vlmcsd.pid', ); +function load_nginx_config(int $kms_port, int $http_port): void { + $nginx_config = "server { + listen $http_port; + listen [::]:$http_port ipv6only=on; + + location /assets { + root /kms-server; + } + + location / { + include fastcgi_params; + fastcgi_pass unix:/run/php-fpm.sock; + if (\$http_user_agent ~* (curl|wget)) { + set \$cli_mode true; + } + fastcgi_param KMS_PORT $kms_port; + fastcgi_param KMS_CLI \$cli_mode; + fastcgi_param SCRIPT_FILENAME /kms-server/src/Route.php; + }\n}\n"; + logging::debug("Nginx configure ->\n" . $nginx_config); + $nginx_file = fopen('/etc/nginx/kms.conf', 'w'); + fwrite($nginx_file, $nginx_config); // save nginx configure file + fclose($nginx_file); +} + +function load_vlmcsd_command(int $kms_port): void { // add port option for vlmcsd + global $VLMCSD; + if ($kms_port != 1688) { // not default kms port + array_push($VLMCSD['command'], '-P', strval($kms_port)); + } +} + +function get_param(string $field, string $default): string { + global $argv; + if (!in_array($field, $argv)) { // field not exist + return $default; + } + $index = array_search($field, $argv) + 1; + if ($index == sizeof($argv)) { // reach arguments end + return $default; + } + return $argv[$index]; // return next argument +} + +function load_params(): void { + global $argv; + if (in_array('--debug', $argv)) { // enter debug mode + logging::$logLevel = logging::DEBUG; + } + + global $KMS_PORT; + $KMS_PORT = intval(get_param('--kms-port', strval($KMS_PORT))); + if ($KMS_PORT < 1 || $KMS_PORT > 65535) { // 1 ~ 65535 + logging::critical('Illegal KMS Port -> ' . $KMS_PORT); + exit; + } + if ($KMS_PORT != 1688) { // not default kms port + logging::warning('KMS Server Port -> ' . $KMS_PORT); + } else { + logging::debug('KMS Server Port -> ' . $KMS_PORT); + } + + global $HTTP_PORT; + $HTTP_PORT = intval(get_param('--http-port', strval($HTTP_PORT))); + if ($HTTP_PORT < 1 || $HTTP_PORT > 65535) { // 1 ~ 65535 + logging::critical('Illegal HTTP Port -> ' . $HTTP_PORT); + exit; + } + if ($HTTP_PORT != 1689) { // not default http port + logging::warning('HTTP Server Port -> ' . $HTTP_PORT); + } else { + logging::debug('HTTP Server Port -> ' . $HTTP_PORT); + } +} + +function start_process(): void { // start sub processes + global $NGINX, $PHP_FPM, $VLMCSD; + new Process($NGINX['command']); + logging::info('Start nginx server...OK'); + new Process($PHP_FPM['command']); + logging::info('Start php-fpm server...OK'); + new Process($VLMCSD['command']); + logging::info('Start vlmcsd server...OK'); +} + declare(ticks = 1); pcntl_signal(SIGCHLD, function() { // receive SIGCHLD signal pcntl_wait($status, WNOHANG); // avoid zombie process }); pcntl_signal(SIGTERM, function() { // receive SIGTERM signal - global $nginx, $phpFpm, $vlmcsd; + global $NGINX, $PHP_FPM, $VLMCSD; logging::info('Get SIGTERM -> exit'); - subExit($nginx['pidFile'], $phpFpm['pidFile'], $vlmcsd['pidFile']); + subExit($NGINX['pidFile'], $PHP_FPM['pidFile'], $VLMCSD['pidFile']); }); pcntl_signal(SIGINT, function() { // receive SIGINT signal - global $nginx, $phpFpm, $vlmcsd; + global $NGINX, $PHP_FPM, $VLMCSD; logging::info('Get SIGINT -> exit'); - subExit($nginx['pidFile'], $phpFpm['pidFile'], $vlmcsd['pidFile']); + subExit($NGINX['pidFile'], $PHP_FPM['pidFile'], $VLMCSD['pidFile']); }); -if (in_array('--debug', $argv)) { // enter debug mode - logging::$logLevel = logging::DEBUG; -} - -$KMS_PORT = 1688; // kms expose port -> only in message output -if (sizeof(getopt('', ['port:'])) == 1) { // port option - $KMS_PORT = getopt('', ['port:'])['port']; - if (is_array($KMS_PORT)) { - $KMS_PORT = end($KMS_PORT); - } -} -logging::debug('KMS Server Port -> ' . $KMS_PORT); -if ($KMS_PORT != 1688) { - array_push($vlmcsd['command'], '-P', strval($KMS_PORT)); -} -$php_env_file = fopen('/etc/nginx/kms_params', 'w'); -fwrite($php_env_file, 'fastcgi_param KMS_PORT "' . $KMS_PORT . '";' . PHP_EOL); -fclose($php_env_file); - logging::info('Loading kms-server (' . $VERSION . ')'); -new Process($nginx['command']); -logging::info('Start nginx server...OK'); -new Process($phpFpm['command']); -logging::info('Start php-fpm server...OK'); -new Process($vlmcsd['command']); -logging::info('Start vlmcsd server...OK'); +load_params(); +load_vlmcsd_command($KMS_PORT); +load_nginx_config($KMS_PORT, $HTTP_PORT); +start_process(); logging::info('Enter daemon process'); while (true) { // start daemon for ($i = 0; $i < 500; $i++) { // sleep 5s msDelay(10); // return main loop every 10ms } - daemon($nginx); - daemon($phpFpm); - daemon($vlmcsd); + daemon($NGINX); + daemon($PHP_FPM); + daemon($VLMCSD); } diff --git a/nginx/kms.conf b/nginx/kms.conf deleted file mode 100644 index a6cb4a0..0000000 --- a/nginx/kms.conf +++ /dev/null @@ -1,25 +0,0 @@ -server { - listen 1689; - 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; - if ($http_user_agent ~* (curl|wget)) { - set $query_param $query_param&cli=true; - } - include kms_params; - include fastcgi_params; - fastcgi_pass 127.0.0.1:9000; - fastcgi_param QUERY_STRING $query_param; - fastcgi_param SCRIPT_FILENAME $kms_dir/src/Route.php; - } -} diff --git a/src/Basis.php b/src/Basis.php index 287f2f2..65f1f21 100644 --- a/src/Basis.php +++ b/src/Basis.php @@ -64,10 +64,10 @@ function getHost(): string { } function getPort(): int { - if (getenv("KMS_PORT") == null) { + if (getenv('KMS_PORT') == null) { return 1688; // default server port } - return intval(getenv("KMS_PORT")); + return intval(getenv('KMS_PORT')); } function officeInfo(): array { // office dir and kms key for different version diff --git a/src/Process.php b/src/Process.php index ea3d867..9b8e168 100644 --- a/src/Process.php +++ b/src/Process.php @@ -1,5 +1,7 @@ `' . implode(' ', $command) . '`'); $this->process = proc_open($command, $desc, $pipes, null, $env); // start process if (is_resource($this->process)) { // process start success $this->pid = proc_get_status($this->process)['pid']; diff --git a/src/Route.php b/src/Route.php index 65c5246..374142a 100644 --- a/src/Route.php +++ b/src/Route.php @@ -8,7 +8,16 @@ require_once 'KmsWeb.php'; $kmsHost = getHost(); // kms server address $kmsPort = getPort(); // kms server port $url = $_SERVER['DOCUMENT_URI']; // request url -$isCli = ($_GET['cli'] == 'true'); // shell or web browser +$isCli = (getenv('KMS_CLI') === 'true'); // shell or web browser + +if ($url == '/json') { // show keys in json format + mimeJson(); + echo json_encode(array( + 'win' => getKeys(), // win keys + 'win-server' => getKeys(true), // win-server keys + )); + return; // skip following process +} $isGbk = false; // utf-8 or gbk $isJson = false; // json output