{"id":339,"date":"2025-09-17T10:42:18","date_gmt":"2025-09-17T10:42:18","guid":{"rendered":"https:\/\/blog.chaiyakul.com\/?p=339"},"modified":"2025-09-17T10:42:50","modified_gmt":"2025-09-17T10:42:50","slug":"ex-ssh-to-php-with-user","status":"publish","type":"post","link":"https:\/\/blog.chaiyakul.com\/index.php\/2025\/09\/17\/ex-ssh-to-php-with-user\/","title":{"rendered":"\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07\u0e01\u0e32\u0e23\u0e41\u0e1b\u0e25\u0e07\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07 SSH \u0e40\u0e1b\u0e47\u0e19 PHP \u0e14\u0e49\u0e27\u0e22\u0e2a\u0e34\u0e17\u0e18\u0e34\u0e4c user \u0e1b\u0e01\u0e15\u0e34"},"content":{"rendered":"\n<p>\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07 SSH<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&#x5B;root@localhost ~]# su - mill \nLast login: Thu Aug 14 17:17:25 +07 2025 on pts\/0 &#x5B;mill@localhost ~]$ export DISPLAY=:0 \n&#x5B;mill@localhost ~]$ xhost +SI:localuser:root sudo DISPLAY=:0 \/home\/mill\/restart_webviewer.sh\n<\/pre><\/div>\n\n\n<p>\u0e17\u0e33\u0e43\u0e2b\u0e49\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e17\u0e35\u0e48\u0e04\u0e38\u0e13\u0e23\u0e31\u0e19\u0e14\u0e49\u0e27\u0e22 shell \u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e23\u0e31\u0e19\u0e08\u0e32\u0e01 <strong>PHP<\/strong> \u0e44\u0e14\u0e49 \u0e42\u0e14\u0e22\u0e27\u0e34\u0e18\u0e35\u0e17\u0e35\u0e48\u0e1b\u0e25\u0e2d\u0e14\u0e20\u0e31\u0e22\u0e41\u0e25\u0e30\u0e17\u0e33\u0e07\u0e32\u0e19\u0e44\u0e14\u0e49\u0e40\u0e2b\u0e21\u0e37\u0e2d\u0e19\u0e01\u0e31\u0e19<\/p>\n\n\n\n<p>\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07 PHP<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\/\/ \u0e23\u0e31\u0e19\u0e42\u0e14\u0e22 user mill (\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e49 root) \u0e1a\u0e19 GUI session \u0e02\u0e2d\u0e07 mill\n\n\/\/ 1. \u0e15\u0e31\u0e49\u0e07 DISPLAY\nputenv(&#039;DISPLAY=:0&#039;);\n\n\/\/ 2. \u0e2d\u0e19\u0e38\u0e0d\u0e32\u0e15 root \u0e40\u0e02\u0e49\u0e32\u0e16\u0e36\u0e07 X server (\u0e16\u0e49\u0e32\u0e08\u0e33\u0e40\u0e1b\u0e47\u0e19)\nexec(&#039;xhost +SI:localuser:root 2&gt;&amp;1&#039;, $xhost_output, $xhost_status);\n\n\/\/ 3. \u0e23\u0e31\u0e19\u0e2a\u0e04\u0e23\u0e34\u0e1b\u0e15\u0e4c restart_webviewer.sh \u0e14\u0e49\u0e27\u0e22 sudo (\u0e15\u0e49\u0e2d\u0e07\u0e15\u0e31\u0e49\u0e07 NOPASSWD \u0e43\u0e19 sudoers)\nexec(&#039;sudo DISPLAY=:0 \/home\/mill\/restart_webviewer.sh 2&gt;&amp;1&#039;, $output, $status);\n\n\/\/ 4. \u0e41\u0e2a\u0e14\u0e07\u0e1c\u0e25\u0e25\u0e31\u0e1e\u0e18\u0e4c\necho &quot;&lt;h3&gt;Output of xhost:&lt;\/h3&gt;&quot;;\necho &quot;&lt;pre&gt;&quot; . implode(&quot;\\n&quot;, $xhost_output) . &quot;&lt;\/pre&gt;&quot;;\n\necho &quot;&lt;h3&gt;Output of restart_webviewer.sh:&lt;\/h3&gt;&quot;;\necho &quot;&lt;pre&gt;&quot; . implode(&quot;\\n&quot;, $output) . &quot;&lt;\/pre&gt;&quot;;\n?&gt;\n<\/pre><\/div>\n\n\n<p>\u0e02\u0e31\u0e49\u0e19\u0e15\u0e2d\u0e19\u0e2a\u0e33\u0e04\u0e31\u0e0d<\/p>\n\n\n\n<p>1.<strong>\u0e43\u0e2b\u0e49 PHP \u0e43\u0e0a\u0e49 user mill<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0e16\u0e49\u0e32\u0e40\u0e27\u0e47\u0e1a\u0e23\u0e31\u0e19\u0e14\u0e49\u0e27\u0e22 Apache\/NGINX \u0e43\u0e2b\u0e49\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19 user \u0e02\u0e2d\u0e07\u0e40\u0e27\u0e47\u0e1a\u0e40\u0e1b\u0e47\u0e19 <code>mill<\/code><\/li>\n\n\n\n<li>\u0e2b\u0e23\u0e37\u0e2d\u0e43\u0e0a\u0e49 <code>sudo NOPASSWD<\/code> \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e2a\u0e04\u0e23\u0e34\u0e1b\u0e15\u0e4c:<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nsudo visudo\n<\/pre><\/div>\n\n\n<p>\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nmill ALL=(ALL) NOPASSWD: \/home\/mill\/restart_webviewer.sh\n<\/pre><\/div>\n\n\n<p>2.X server \u0e15\u0e49\u0e2d\u0e07\u0e23\u0e31\u0e19\u0e2d\u0e22\u0e39\u0e48<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0e15\u0e49\u0e2d\u0e07\u0e21\u0e35 session GUI \u0e02\u0e2d\u0e07 user <code>mill<\/code> \u0e40\u0e1b\u0e34\u0e14\u0e2d\u0e22\u0e39\u0e48 (<code>DISPLAY=:0<\/code>)<\/li>\n\n\n\n<li>\u0e2b\u0e23\u0e37\u0e2d\u0e43\u0e0a\u0e49 Xvfb \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a headless<\/li>\n<\/ul>\n\n\n\n<p>\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e2b\u0e15\u0e38<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>xhost +SI:localuser:root<\/code> \u0e2d\u0e19\u0e38\u0e0d\u0e32\u0e15 root \u0e43\u0e0a\u0e49 X server<\/li>\n\n\n\n<li>\u0e01\u0e32\u0e23\u0e23\u0e31\u0e19 Wine \u0e08\u0e32\u0e01 PHP \u0e08\u0e30\u0e15\u0e49\u0e2d\u0e07\u0e2d\u0e22\u0e39\u0e48\u0e1a\u0e19 session GUI \u0e02\u0e2d\u0e07 user mill<\/li>\n\n\n\n<li>\u0e1b\u0e25\u0e2d\u0e14\u0e20\u0e31\u0e22\u0e17\u0e35\u0e48\u0e2a\u0e38\u0e14\u0e04\u0e37\u0e2d <strong>\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e49 root \u0e23\u0e31\u0e19 Wine \u0e41\u0e15\u0e48\u0e43\u0e2b\u0e49 PHP \u0e23\u0e31\u0e19\u0e14\u0e49\u0e27\u0e22 user mill \u0e42\u0e14\u0e22\u0e15\u0e23\u0e07<\/strong><\/li>\n<\/ul>\n\n\n\n<p><u><strong>\u0e16\u0e49\u0e32\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e17\u0e33\u0e40\u0e1b\u0e47\u0e19\u0e1b\u0e38\u0e48\u0e21<\/strong><\/u><\/p>\n\n\n\n<p>\u0e19\u0e35\u0e48\u0e40\u0e1b\u0e47\u0e19 <strong>PHP + HTML \u0e2b\u0e19\u0e49\u0e32\u0e40\u0e14\u0e35\u0e22\u0e27<\/strong> \u0e17\u0e35\u0e48\u0e21\u0e35\u0e1b\u0e38\u0e48\u0e21 \u201cRestart WebViewer\u201d \u0e41\u0e25\u0e30\u0e41\u0e2a\u0e14\u0e07 log output \u0e2b\u0e25\u0e31\u0e07\u0e08\u0e32\u0e01\u0e01\u0e14\u0e1b\u0e38\u0e48\u0e21<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n$output = &#x5B;];\n$status = null;\n\n\/\/ \u0e16\u0e49\u0e32\u0e21\u0e35\u0e01\u0e32\u0e23\u0e01\u0e14\u0e1b\u0e38\u0e48\u0e21\nif (isset($_POST&#x5B;&#039;restart&#039;])) {\n    \/\/ \u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32 DISPLAY\n    putenv(&#039;DISPLAY=:0&#039;);\n\n    \/\/ \u0e2d\u0e19\u0e38\u0e0d\u0e32\u0e15 root \u0e43\u0e0a\u0e49 X server (\u0e16\u0e49\u0e32 script \u0e43\u0e0a\u0e49 sudo)\n    exec(&#039;xhost +SI:localuser:root 2&gt;&amp;1&#039;, $xhost_output, $xhost_status);\n\n    \/\/ \u0e23\u0e31\u0e19\u0e2a\u0e04\u0e23\u0e34\u0e1b\u0e15\u0e4c restart_webviewer.sh\n    exec(&#039;sudo DISPLAY=:0 \/home\/mill\/restart_webviewer.sh 2&gt;&amp;1&#039;, $output, $status);\n}\n?&gt;\n\n&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;th&quot;&gt;\n&lt;head&gt;\n&lt;meta charset=&quot;UTF-8&quot;&gt;\n&lt;title&gt;Restart WebViewer&lt;\/title&gt;\n&lt;style&gt;\n    body { font-family: Arial, sans-serif; margin: 20px; }\n    button { padding: 10px 20px; font-size: 16px; }\n    pre { background: #f0f0f0; padding: 10px; border: 1px solid #ccc; }\n&lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n\n&lt;h2&gt;Restart WebViewer&lt;\/h2&gt;\n\n&lt;form method=&quot;post&quot;&gt;\n    &lt;button type=&quot;submit&quot; name=&quot;restart&quot;&gt;Restart WebViewer&lt;\/button&gt;\n&lt;\/form&gt;\n\n&lt;?php if (!empty($output)): ?&gt;\n    &lt;h3&gt;Output:&lt;\/h3&gt;\n    &lt;pre&gt;&lt;?php echo htmlspecialchars(implode(&quot;\\n&quot;, $output)); ?&gt;&lt;\/pre&gt;\n&lt;?php endif; ?&gt;\n\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/pre><\/div>\n\n\n<p>\u0e27\u0e34\u0e18\u0e35\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19<\/p>\n\n\n\n<p>1.\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e44\u0e1f\u0e25\u0e4c\u0e40\u0e1b\u0e47\u0e19 <code>restart_webviewer.php<\/code> \u0e43\u0e19\u0e40\u0e27\u0e47\u0e1a\u0e40\u0e0b\u0e34\u0e23\u0e4c\u0e1f\u0e40\u0e27\u0e2d\u0e23\u0e4c<\/p>\n\n\n\n<p>2.\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a <strong>sudoers<\/strong> \u0e43\u0e2b\u0e49 <code>mill<\/code> \u0e2b\u0e23\u0e37\u0e2d user \u0e40\u0e27\u0e47\u0e1a\u0e23\u0e31\u0e19 <code>\/home\/mill\/restart_webviewer.sh<\/code> \u0e44\u0e14\u0e49\u0e42\u0e14\u0e22\u0e44\u0e21\u0e48\u0e15\u0e49\u0e2d\u0e07\u0e43\u0e2a\u0e48 password:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nsudo visudo\n# \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14:\napache ALL=(ALL) NOPASSWD: \/home\/mill\/restart_webviewer.sh\n# \u0e2b\u0e23\u0e37\u0e2d\u0e16\u0e49\u0e32\u0e43\u0e0a\u0e49 nginx: www-data ALL=(ALL) NOPASSWD: \/home\/mill\/restart_webviewer.sh\n<\/pre><\/div>\n\n\n<p>3.\u0e40\u0e1b\u0e34\u0e14\u0e40\u0e1a\u0e23\u0e32\u0e27\u0e4c\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e40\u0e02\u0e49\u0e32:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nhttp:\/\/&#x5B;server-ip]\/restart_webviewer.php\n<\/pre><\/div>\n\n\n<p>4.\u0e01\u0e14\u0e1b\u0e38\u0e48\u0e21 \u201cRestart WebViewer\u201d<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0e23\u0e30\u0e1a\u0e1a\u0e08\u0e30\u0e23\u0e31\u0e19\u0e2a\u0e04\u0e23\u0e34\u0e1b\u0e15\u0e4c<\/li>\n\n\n\n<li>\u0e41\u0e2a\u0e14\u0e07 log output \u0e2b\u0e25\u0e31\u0e07\u0e1b\u0e38\u0e48\u0e21<\/li>\n<\/ul>\n\n\n\n<p>\ud83d\udca1 <strong>\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e2b\u0e15\u0e38\u0e2a\u0e33\u0e04\u0e31\u0e0d<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>X server \u0e02\u0e2d\u0e07 user <code>mill<\/code> \u0e15\u0e49\u0e2d\u0e07\u0e23\u0e31\u0e19\u0e2d\u0e22\u0e39\u0e48 (<code>DISPLAY=:0<\/code>)<\/li>\n\n\n\n<li>\u0e01\u0e32\u0e23\u0e43\u0e2b\u0e49 PHP \u0e23\u0e31\u0e19\u0e2a\u0e04\u0e23\u0e34\u0e1b\u0e15\u0e4c\u0e14\u0e49\u0e27\u0e22 sudo \u0e21\u0e35\u0e04\u0e27\u0e32\u0e21\u0e40\u0e2a\u0e35\u0e48\u0e22\u0e07\u0e14\u0e49\u0e32\u0e19\u0e04\u0e27\u0e32\u0e21\u0e1b\u0e25\u0e2d\u0e14\u0e20\u0e31\u0e22\n<ul class=\"wp-block-list\">\n<li>\u0e41\u0e19\u0e30\u0e19\u0e33\u0e43\u0e2b\u0e49 <strong>\u0e08\u0e33\u0e01\u0e31\u0e14\u0e44\u0e1f\u0e25\u0e4c\u0e19\u0e35\u0e49\u0e40\u0e02\u0e49\u0e32\u0e16\u0e36\u0e07\u0e40\u0e09\u0e1e\u0e32\u0e30\u0e1c\u0e39\u0e49\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e16\u0e37\u0e2d\u0e44\u0e14\u0e49<\/strong><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07 SSH \u0e17\u0e33\u0e43\u0e2b\u0e49\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e17\u0e35\u0e48\u0e04\u0e38\u0e13\u0e23\u0e31\u0e19\u0e14\u0e49\u0e27\u0e22 shell \u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e23\u0e31\u0e19\u0e08\u0e32\u0e01  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","footnotes":""},"categories":[105,163,162,9,161],"tags":[],"class_list":["post-339","post","type-post","status-publish","format-standard","hentry","category-centos","category-gui","category-html","category-linux","category-php"],"_links":{"self":[{"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/posts\/339","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/comments?post=339"}],"version-history":[{"count":2,"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/posts\/339\/revisions"}],"predecessor-version":[{"id":341,"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/posts\/339\/revisions\/341"}],"wp:attachment":[{"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/media?parent=339"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/categories?post=339"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.chaiyakul.com\/index.php\/wp-json\/wp\/v2\/tags?post=339"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}