From 6d379a4dd638cc4694e0e1ddef5d81827f9478ee Mon Sep 17 00:00:00 2001 From: ljm42 Date: Sun, 17 Mar 2024 20:23:51 -0700 Subject: [PATCH 1/8] Add outgoing proxy support --- .../include/DockerClient.php | 6 +- .../include/Helpers.php | 4 + .../include/UnraidCheck.php | 5 +- .../scripts/PluginAPI.php | 2 + emhttp/plugins/dynamix/include/Helpers.php | 52 ++++++ .../plugins/dynamix/include/ProvisionCert.php | 5 +- emhttp/plugins/dynamix/include/ReplaceKey.php | 4 + .../dynamix/include/update.wireguard.php | 8 +- emhttp/plugins/dynamix/scripts/diagnostics | 12 +- etc/rc.d/rc.local | 4 + sbin/set_proxy | 152 ++++++++++++++++++ 11 files changed, 237 insertions(+), 17 deletions(-) create mode 100644 sbin/set_proxy diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index a56a8ffe8..20154a3a4 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -14,6 +14,7 @@ /", $source) > 0) { $parse = parse_url($url); @@ -395,6 +397,7 @@ class DockerUpdate{ public function download_url($url, $path='') { $ch = curl_init(); + $ch = getProxyCurlOpt($url, $ch); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -411,6 +414,7 @@ class DockerUpdate{ public function download_url_and_headers($url, $headers=[], $path='') { $ch = curl_init(); + $ch = getProxyCurlOpt($url, $ch); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); diff --git a/emhttp/plugins/dynamix.docker.manager/include/Helpers.php b/emhttp/plugins/dynamix.docker.manager/include/Helpers.php index dff9214a1..2254e5fae 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/Helpers.php +++ b/emhttp/plugins/dynamix.docker.manager/include/Helpers.php @@ -12,6 +12,9 @@ */ ?> $e->getMessage()), JSON_PRETTY_PRINT); } @@ -159,7 +160,7 @@ class UnraidOsCheck // send notification if a newer version is available and not ignored $isNewerVersion = array_key_exists('isNewer',$responseMutated) ? $responseMutated['isNewer'] : false; - $isReleaseIgnored = in_array($responseMutated['version'], $this->getIgnoredReleases()); + $isReleaseIgnored = array_key_exists('version',$responseMutated) ? in_array($responseMutated['version'], $this->getIgnoredReleases()) : false; if ($responseMutated && $isNewerVersion && !$isReleaseIgnored) { $output = _var($notify,'plugin'); diff --git a/emhttp/plugins/dynamix.plugin.manager/scripts/PluginAPI.php b/emhttp/plugins/dynamix.plugin.manager/scripts/PluginAPI.php index 66b457448..8c090f301 100644 --- a/emhttp/plugins/dynamix.plugin.manager/scripts/PluginAPI.php +++ b/emhttp/plugins/dynamix.plugin.manager/scripts/PluginAPI.php @@ -13,6 +13,7 @@ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php"; require_once "$docroot/plugins/dynamix/include/Secure.php"; +require_once "$docroot/webGui/include/Helpers.php"; //add translations $_SERVER['REQUEST_URI'] = "plugins"; @@ -20,6 +21,7 @@ require_once "$docroot/plugins/dynamix/include/Translations.php"; function download_url($url, $path = "") { $ch = curl_init(); + $ch = getProxyCurlOpt($url, $ch); curl_setopt_array($ch,[ CURLOPT_URL => $url, CURLOPT_FRESH_CONNECT => true, diff --git a/emhttp/plugins/dynamix/include/Helpers.php b/emhttp/plugins/dynamix/include/Helpers.php index d2689c057..2a91ff7fb 100644 --- a/emhttp/plugins/dynamix/include/Helpers.php +++ b/emhttp/plugins/dynamix/include/Helpers.php @@ -291,4 +291,56 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false) { break; } } +// use when calling file_get_contents, fopen, or similar on a url +// reads proxy.ini and determines whether to proxy the request +// example usage: file_get_contents($url, false, getProxyStreamContext($url)); +function getProxyStreamContext($url, $streamContextOptions = [], $http_proxy_override = null, $no_proxy_override = null) { + $url_host=parse_url($url, PHP_URL_HOST); + $proxy = (array)@parse_ini_file("/var/local/emhttp/proxy.ini",true); + + $http_proxy = $http_proxy_override ?? _var($proxy,'http_proxy'); + $no_proxy = $no_proxy_override ?? _var($proxy,'no_proxy'); + $no_proxy_arr = ($no_proxy) ? explode (",", $no_proxy) : []; + + // php does not support sock5 proxies in HTTP context options, only http proxies + // do not proxy hosts listed in the no_proxy environment variable + if ($http_proxy && str_starts_with($http_proxy, 'http://') && ! in_array($url_host, $no_proxy_arr)) { + $auth = null; + $proxy_parts = parse_url($http_proxy); + if (isset($proxy_parts['user']) && isset($proxy_parts['pass'])) { + // rebuild $http_proxy url without user:pass + $http_proxy = $proxy_parts['scheme'] . '://' . $proxy_parts['host'] . (isset($proxy_parts['port']) ? ':' . $proxy_parts['port'] : ''); + // prep for basic auth + $auth = base64_encode(urldecode($proxy_parts['user']).':'.urldecode($proxy_parts['pass'])); + } + $http_proxy = str_replace('http://', 'tcp://', $http_proxy); + $streamContextOptions['http']['proxy'] = $http_proxy; + $streamContextOptions['http']['request_fulluri'] = true; + if ($auth) $streamContextOptions['http']['header'] = 'Proxy-Authorization: Basic '.$auth; + } + if (!empty($streamContextOptions)) { + $streamContext=stream_context_create($streamContextOptions); + return $streamContext; + } else { + return null; + } +} +// use after calling curl_init(); +// reads proxy.ini and determines whether to proxy the request +// example usage: $ch = getProxyCurlOpt($url, $ch); +function getProxyCurlOpt($url, $ch, $http_proxy_override = null, $no_proxy_override = null) { + $url_host=parse_url($url, PHP_URL_HOST); + $proxy = (array)@parse_ini_file("/var/local/emhttp/proxy.ini",true); + + $http_proxy = $http_proxy_override ?? _var($proxy,'http_proxy'); + $no_proxy = $no_proxy_override ?? _var($proxy,'no_proxy'); + $no_proxy_arr = ($no_proxy) ? explode (",", $no_proxy) : []; + + // do not proxy hosts listed in the no_proxy environment variable + if ($http_proxy && ! in_array($url_host, $no_proxy_arr)) { + curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true); + curl_setopt($ch, CURLOPT_PROXY, $http_proxy); + } + return $ch; +} ?> diff --git a/emhttp/plugins/dynamix/include/ProvisionCert.php b/emhttp/plugins/dynamix/include/ProvisionCert.php index 51b9564d1..0fdd99096 100644 --- a/emhttp/plugins/dynamix/include/ProvisionCert.php +++ b/emhttp/plugins/dynamix/include/ProvisionCert.php @@ -12,6 +12,7 @@ ?> ['timeout'=>12]]); + $wanip4url = 'https://wanip4.unraid.net'; + $wanip6url = 'https://wanip6.unraid.net'; + $contextOptions['http']['timeout'] = 12; $int_ipv4 = $v4 ? (preg_match("/^$validIP4$/",$ip) ? $ip : (@dns_get_record($ip,DNS_A)[0]['ip'] ?: '')) : ''; - $ext_ipv4 = $v4 ? (@file_get_contents('https://wanip4.unraid.net',false,$context) ?: '') : ''; + $ext_ipv4 = $v4 ? (@file_get_contents($wanip4url,false,getProxyStreamContext($wanip4url,$contextOptions)) ?: '') : ''; $int_ipv6 = $v6 ? (preg_match("/^$validIP6$/",$ip) ? $ip : (@dns_get_record($ip,DNS_AAAA)[0]['ipv6'] ?: '')) : ''; - $ext_ipv6 = $v6 ? (@file_get_contents('https://wanip6.unraid.net',false,$context) ?: '') : ''; + $ext_ipv6 = $v6 ? (@file_get_contents($wanip6url,false,getProxyStreamContext($wanip6url,$contextOptions)) ?: '') : ''; echo "$int_ipv4;$ext_ipv4;$int_ipv6;$ext_ipv6"; break; case 'addtunnel': diff --git a/emhttp/plugins/dynamix/scripts/diagnostics b/emhttp/plugins/dynamix/scripts/diagnostics index 397fed3ad..c1ced137d 100755 --- a/emhttp/plugins/dynamix/scripts/diagnostics +++ b/emhttp/plugins/dynamix/scripts/diagnostics @@ -25,6 +25,7 @@ $zip = $all ? ($argv[2]??'') : ($argv[1]??''); $cli = empty($zip); $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); +require_once "$docroot/webGui/include/Helpers.php"; require_once "$docroot/webGui/include/Wrappers.php"; $folders = ['/boot','/boot/config','/boot/config/plugins','/boot/syslinux','/var/log','/var/log/plugins','/boot/extra','/var/log/packages','/var/lib/pkgtools/packages','/tmp']; @@ -115,18 +116,9 @@ function maskIP($file) { // anonymize full IPv6 addresses run("sed -ri 's/([\"\[ ]([0-9a-f]{1,4}:){4})(([0-9a-f]{1,4}:){3}|:)([0-9a-f]{1,4})([/\" .]|$)/\\1XXXX:XXXX:XXXX:\\5\\6/g' ".escapeshellarg($file)." 2>/dev/null"); } - -function cache_only($disk) { - return _var($disk,'type')=='Cache'; -} -function cache_filter($disks) { - return array_filter($disks,'cache_only'); -} -function pools_filter($disks) { - return array_unique(array_map('prefix',array_keys(cache_filter($disks)))); -} function download_url($url, $path="", $bg=false, $timeout=15) { $ch = curl_init(); + $ch = getProxyCurlOpt($url, $ch); curl_setopt_array($ch,[ CURLOPT_URL => $url, CURLOPT_FRESH_CONNECT => true, diff --git a/etc/rc.d/rc.local b/etc/rc.d/rc.local index b73cd534f..f71112bf4 100755 --- a/etc/rc.d/rc.local +++ b/etc/rc.d/rc.local @@ -14,6 +14,10 @@ # run & log functions . /etc/rc.d/rc.runlog +# load proxy environment vars so it is used for plugin updates and the go script +/usr/local/sbin/set_proxy +[[ -x /etc/profile.d/proxy.sh ]] && . /etc/profile.d/proxy.sh + # irqbalance daemon distributes interrupts over processors and cores # if [[ -x /usr/sbin/irqbalance ]]; then # /usr/sbin/irqbalance diff --git a/sbin/set_proxy b/sbin/set_proxy new file mode 100644 index 000000000..0e0eae31e --- /dev/null +++ b/sbin/set_proxy @@ -0,0 +1,152 @@ +#!/bin/bash +# +# script: set_proxy +# +# Copyright 2005-2024, Lime Technology +# +# call this script (/usr/local/sbin/set_proxy) when /boot/config/proxy.cfg changes + +# proxy.cfg is the source of all proxy information +CFG=/boot/config/proxy.cfg + +# these files are generated by this script based on the data in proxy.cfg +PROXY_SH=/etc/profile.d/proxy.sh +PROXY_INI=/usr/local/emhttp/state/proxy.ini +WGET=/root/.wgetrc + +# random file extension for atomic writes +RND=$RANDOM + +VERBOSE= +[[ "$1" == "-v" ]] && VERBOSE=1 + +# global vars defined later +proxy_active= +proxy_url= +no_proxy= + +# write environment variables to /etc/profile.d/proxy.sh +set_proxy_sh() { + local FILE + FILE="${PROXY_SH}" + cat <"${FILE}.${RND}" +#!/bin/bash +# Do not edit. This file is autogenerated by /usr/local/sbin/set_proxy +export http_proxy="${proxy_url}" +export https_proxy="${proxy_url}" +export no_proxy="${no_proxy}" +EOF + chmod 755 "${FILE}.${RND}" + mv "${FILE}.${RND}" "${FILE}" +} + +# clear environment variables from /etc/profile.d/proxy.sh +unset_proxy_sh() { + local FILE + FILE="${PROXY_SH}" + cat <"${FILE}.${RND}" +#!/bin/bash +# Do not edit. This file is autogenerated by /usr/local/sbin/set_proxy +unset http_proxy +unset https_proxy +unset no_proxy +EOF + chmod 755 "${FILE}.${RND}" + mv "${FILE}.${RND}" "${FILE}" +} + +# write /usr/local/emhttp/state/proxy.ini +set_proxy_ini() { + local FILE + FILE="${PROXY_INI}" + cat <"${FILE}.${RND}" +http_proxy="${proxy_url}" +https_proxy="${proxy_url}" +no_proxy="${no_proxy}" +EOF + chmod 644 "${FILE}.${RND}" + mv "${FILE}.${RND}" "${FILE}" +} + +# clear /usr/local/emhttp/state/proxy.ini +unset_proxy_ini() { + # vars are empty now, call set_proxy_ini to add empty vars to proxy.ini + set_proxy_ini +} + +# write /root/.wgetrc +set_wget() { + local FILE + FILE="${WGET}" + cat <"${FILE}.${RND}" +# Do not edit. This file is autogenerated by /usr/local/sbin/set_proxy +use_proxy=yes +http_proxy=${proxy_url} +https_proxy=${proxy_url} +no_proxy="${no_proxy}" +EOF + chmod 644 "${FILE}.${RND}" + mv "${FILE}.${RND}" "${FILE}" +} + +# clear /root/.wgetrc +unset_wget() { + local FILE + FILE="${WGET}" + [[ -f "${FILE}" ]] && rm "${FILE}" +} + +# generate proxy files +add_proxy_to_generated_files_and_exit() { + echo "generating proxy files" + set_proxy_sh + set_proxy_ini + set_wget + [[ -n "${VERBOSE}" ]] && display_generated_files + exit 0 +} + +# remove proxy info from all generated files and exit +remove_proxy_from_generated_files_and_exit() { + echo "removing proxy info from generated files" + unset_proxy_sh + unset_proxy_ini + unset_wget + [[ -n "${VERBOSE}" ]] && display_generated_files + exit 0 +} + +display_generated_files() { + echo + display_generated_file "${PROXY_SH}" + display_generated_file "${PROXY_INI}" + display_generated_file "${WGET}" +} + +display_generated_file() { + local FILE + FILE=$1 + echo "${FILE}" + [[ -f "${FILE}" ]] && cat "${FILE}" || echo "file does not exist" + echo +} + +# if no proxy config, remove proxy info from all generated files and exit +[[ ! -f "${CFG}" ]] && remove_proxy_from_generated_files_and_exit + +# read current proxy information from /boot/config/proxy.cfg +# shellcheck source=/dev/null +. <(/usr/bin/fromdos <"${CFG}") + +# determine proxy information +proxy_url_var="proxy_url_${proxy_active:=}" +proxy_url="${!proxy_url_var}" + +# if no active proxies, remove proxy info from all generated files and exit +if [[ "${proxy_active:=0}" == "0" || "${proxy_url}" == "" ]]; then + remove_proxy_from_generated_files_and_exit +fi + +# proxies are defined, write generated files +no_proxy="127.0.0.1,localhost" +add_proxy_to_generated_files_and_exit From 77bd950c6d27bea903db3227b21477c791afdeaa Mon Sep 17 00:00:00 2001 From: ljm42 Date: Mon, 18 Mar 2024 14:22:57 -0700 Subject: [PATCH 2/8] remove proxy.ini, use environment variables instead --- emhttp/plugins/dynamix/include/Helpers.php | 16 ++++------ sbin/set_proxy | 37 +++++++--------------- 2 files changed, 18 insertions(+), 35 deletions(-) diff --git a/emhttp/plugins/dynamix/include/Helpers.php b/emhttp/plugins/dynamix/include/Helpers.php index 2a91ff7fb..f5eb6aac4 100644 --- a/emhttp/plugins/dynamix/include/Helpers.php +++ b/emhttp/plugins/dynamix/include/Helpers.php @@ -292,14 +292,13 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false) { } } // use when calling file_get_contents, fopen, or similar on a url -// reads proxy.ini and determines whether to proxy the request +// reads environment variables and determines whether to proxy the request // example usage: file_get_contents($url, false, getProxyStreamContext($url)); function getProxyStreamContext($url, $streamContextOptions = [], $http_proxy_override = null, $no_proxy_override = null) { $url_host=parse_url($url, PHP_URL_HOST); - $proxy = (array)@parse_ini_file("/var/local/emhttp/proxy.ini",true); - - $http_proxy = $http_proxy_override ?? _var($proxy,'http_proxy'); - $no_proxy = $no_proxy_override ?? _var($proxy,'no_proxy'); + + $http_proxy = $http_proxy_override ?? getenv('http_proxy'); + $no_proxy = $no_proxy_override ?? getenv('no_proxy'); $no_proxy_arr = ($no_proxy) ? explode (",", $no_proxy) : []; // php does not support sock5 proxies in HTTP context options, only http proxies @@ -326,14 +325,13 @@ function getProxyStreamContext($url, $streamContextOptions = [], $http_proxy_ove } } // use after calling curl_init(); -// reads proxy.ini and determines whether to proxy the request +// reads environment variables and determines whether to proxy the request // example usage: $ch = getProxyCurlOpt($url, $ch); function getProxyCurlOpt($url, $ch, $http_proxy_override = null, $no_proxy_override = null) { $url_host=parse_url($url, PHP_URL_HOST); - $proxy = (array)@parse_ini_file("/var/local/emhttp/proxy.ini",true); - $http_proxy = $http_proxy_override ?? _var($proxy,'http_proxy'); - $no_proxy = $no_proxy_override ?? _var($proxy,'no_proxy'); + $http_proxy = $http_proxy_override ?? getenv('http_proxy'); + $no_proxy = $no_proxy_override ?? getenv('no_proxy'); $no_proxy_arr = ($no_proxy) ? explode (",", $no_proxy) : []; // do not proxy hosts listed in the no_proxy environment variable diff --git a/sbin/set_proxy b/sbin/set_proxy index 0e0eae31e..2dcc07841 100644 --- a/sbin/set_proxy +++ b/sbin/set_proxy @@ -11,7 +11,6 @@ CFG=/boot/config/proxy.cfg # these files are generated by this script based on the data in proxy.cfg PROXY_SH=/etc/profile.d/proxy.sh -PROXY_INI=/usr/local/emhttp/state/proxy.ini WGET=/root/.wgetrc # random file extension for atomic writes @@ -55,11 +54,13 @@ EOF mv "${FILE}.${RND}" "${FILE}" } -# write /usr/local/emhttp/state/proxy.ini -set_proxy_ini() { +# write /root/.wgetrc +set_wget() { local FILE - FILE="${PROXY_INI}" + FILE="${WGET}" cat <"${FILE}.${RND}" +# Do not edit. This file is autogenerated by /usr/local/sbin/set_proxy +use_proxy=yes http_proxy="${proxy_url}" https_proxy="${proxy_url}" no_proxy="${no_proxy}" @@ -68,25 +69,8 @@ EOF mv "${FILE}.${RND}" "${FILE}" } -# clear /usr/local/emhttp/state/proxy.ini -unset_proxy_ini() { - # vars are empty now, call set_proxy_ini to add empty vars to proxy.ini - set_proxy_ini -} - -# write /root/.wgetrc -set_wget() { - local FILE - FILE="${WGET}" - cat <"${FILE}.${RND}" -# Do not edit. This file is autogenerated by /usr/local/sbin/set_proxy -use_proxy=yes -http_proxy=${proxy_url} -https_proxy=${proxy_url} -no_proxy="${no_proxy}" -EOF - chmod 644 "${FILE}.${RND}" - mv "${FILE}.${RND}" "${FILE}" +restart_phpfpm () { + /etc/rc.d/rc.php-fpm restart > /dev/null } # clear /root/.wgetrc @@ -100,8 +84,9 @@ unset_wget() { add_proxy_to_generated_files_and_exit() { echo "generating proxy files" set_proxy_sh - set_proxy_ini set_wget + . "${PROXY_SH}" + restart_phpfpm [[ -n "${VERBOSE}" ]] && display_generated_files exit 0 } @@ -110,8 +95,9 @@ add_proxy_to_generated_files_and_exit() { remove_proxy_from_generated_files_and_exit() { echo "removing proxy info from generated files" unset_proxy_sh - unset_proxy_ini unset_wget + . "${PROXY_SH}" + restart_phpfpm [[ -n "${VERBOSE}" ]] && display_generated_files exit 0 } @@ -119,7 +105,6 @@ remove_proxy_from_generated_files_and_exit() { display_generated_files() { echo display_generated_file "${PROXY_SH}" - display_generated_file "${PROXY_INI}" display_generated_file "${WGET}" } From ffcb5b11a1f3463d9036760e633194f47e071a03 Mon Sep 17 00:00:00 2001 From: ljm42 Date: Mon, 18 Mar 2024 14:44:51 -0700 Subject: [PATCH 3/8] Remove special handling for libcurl, use environment variables instead --- .../include/DockerClient.php | 4 ---- .../dynamix.docker.manager/include/Helpers.php | 4 ---- .../scripts/PluginAPI.php | 2 -- emhttp/plugins/dynamix/include/Helpers.php | 17 ----------------- .../plugins/dynamix/include/ProvisionCert.php | 5 +---- emhttp/plugins/dynamix/include/ReplaceKey.php | 4 ---- emhttp/plugins/dynamix/scripts/diagnostics | 1 - 7 files changed, 1 insertion(+), 36 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index 20154a3a4..4a605925f 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -14,7 +14,6 @@ $url, CURLOPT_FRESH_CONNECT => true, diff --git a/emhttp/plugins/dynamix/include/Helpers.php b/emhttp/plugins/dynamix/include/Helpers.php index f5eb6aac4..419f57ddb 100644 --- a/emhttp/plugins/dynamix/include/Helpers.php +++ b/emhttp/plugins/dynamix/include/Helpers.php @@ -324,21 +324,4 @@ function getProxyStreamContext($url, $streamContextOptions = [], $http_proxy_ove return null; } } -// use after calling curl_init(); -// reads environment variables and determines whether to proxy the request -// example usage: $ch = getProxyCurlOpt($url, $ch); -function getProxyCurlOpt($url, $ch, $http_proxy_override = null, $no_proxy_override = null) { - $url_host=parse_url($url, PHP_URL_HOST); - - $http_proxy = $http_proxy_override ?? getenv('http_proxy'); - $no_proxy = $no_proxy_override ?? getenv('no_proxy'); - $no_proxy_arr = ($no_proxy) ? explode (",", $no_proxy) : []; - - // do not proxy hosts listed in the no_proxy environment variable - if ($http_proxy && ! in_array($url_host, $no_proxy_arr)) { - curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true); - curl_setopt($ch, CURLOPT_PROXY, $http_proxy); - } - return $ch; -} ?> diff --git a/emhttp/plugins/dynamix/include/ProvisionCert.php b/emhttp/plugins/dynamix/include/ProvisionCert.php index 0fdd99096..51b9564d1 100644 --- a/emhttp/plugins/dynamix/include/ProvisionCert.php +++ b/emhttp/plugins/dynamix/include/ProvisionCert.php @@ -12,7 +12,6 @@ ?> $url, CURLOPT_FRESH_CONNECT => true, From 78dcc575d6ae3922a34d1661f86936ce2140302b Mon Sep 17 00:00:00 2001 From: ljm42 Date: Mon, 18 Mar 2024 14:51:28 -0700 Subject: [PATCH 4/8] tidy --- .../include/DockerClient.php | 1 + sbin/set_proxy | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index 4a605925f..7e291d2d2 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -14,6 +14,7 @@ "${FILE}.${RND}" # Do not edit. This file is autogenerated by /usr/local/sbin/set_proxy use_proxy=yes -http_proxy="${proxy_url}" -https_proxy="${proxy_url}" +http_proxy=${proxy_url} +https_proxy=${proxy_url} no_proxy="${no_proxy}" EOF chmod 644 "${FILE}.${RND}" mv "${FILE}.${RND}" "${FILE}" } -restart_phpfpm () { - /etc/rc.d/rc.php-fpm restart > /dev/null -} - # clear /root/.wgetrc unset_wget() { local FILE @@ -80,6 +76,11 @@ unset_wget() { [[ -f "${FILE}" ]] && rm "${FILE}" } +# restart_phpfpm whenever the environment variables change +restart_phpfpm () { + /etc/rc.d/rc.php-fpm restart > /dev/null +} + # generate proxy files add_proxy_to_generated_files_and_exit() { echo "generating proxy files" @@ -102,12 +103,14 @@ remove_proxy_from_generated_files_and_exit() { exit 0 } +# when verbose mode enabled display_generated_files() { echo display_generated_file "${PROXY_SH}" display_generated_file "${WGET}" } +# when verbose mode enabled display_generated_file() { local FILE FILE=$1 From cb84d60e006b9d8d5479421eac91c0405b5f9063 Mon Sep 17 00:00:00 2001 From: ljm42 Date: Tue, 19 Mar 2024 11:52:59 -0700 Subject: [PATCH 5/8] Remove special handling for file_get_contents(), use libcurl instead --- .../include/DockerClient.php | 3 +- .../include/UnraidCheck.php | 25 +++++++------- emhttp/plugins/dynamix/include/Helpers.php | 33 ------------------- .../dynamix/include/update.wireguard.php | 23 ++++++++++--- 4 files changed, 33 insertions(+), 51 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index 7e291d2d2..772db2c2d 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -14,7 +14,6 @@ download_url($url); // the following should always exist for GitLab Community Edition or GitLab Enterprise Edition if (preg_match("//", $source) > 0) { $parse = parse_url($url); diff --git a/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php b/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php index df55a63e5..4c64b6ed4 100644 --- a/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php +++ b/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php @@ -126,18 +126,21 @@ class UnraidOsCheck $urlbase = $parsedAltUrl ?? $defaultUrl; $url = $urlbase.'?'.http_build_query($params); - $response = ""; - // use error handler to convert warnings from file_get_contents to errors so they can be captured - function warning_as_error($severity, $message, $filename, $lineno) { - throw new ErrorException($message, 0, $severity, $filename, $lineno); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); + curl_setopt($ch, CURLOPT_TIMEOUT, 45); + curl_setopt($ch, CURLOPT_ENCODING, ""); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_REFERER, ""); + curl_setopt($ch, CURLOPT_FAILONERROR, true); + $response = curl_exec($ch); + if (curl_errno($ch)) { + $response = json_encode(array('error' => curl_error($ch)), JSON_PRETTY_PRINT); } - set_error_handler("warning_as_error"); - try { - $response = file_get_contents($url, false, getProxyStreamContext($url)); - } catch (Exception $e) { - $response = json_encode(array('error' => $e->getMessage()), JSON_PRETTY_PRINT); - } - restore_error_handler(); + curl_close($ch); $responseMutated = json_decode($response, true); if (!$responseMutated) { diff --git a/emhttp/plugins/dynamix/include/Helpers.php b/emhttp/plugins/dynamix/include/Helpers.php index 419f57ddb..d2689c057 100644 --- a/emhttp/plugins/dynamix/include/Helpers.php +++ b/emhttp/plugins/dynamix/include/Helpers.php @@ -291,37 +291,4 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false) { break; } } -// use when calling file_get_contents, fopen, or similar on a url -// reads environment variables and determines whether to proxy the request -// example usage: file_get_contents($url, false, getProxyStreamContext($url)); -function getProxyStreamContext($url, $streamContextOptions = [], $http_proxy_override = null, $no_proxy_override = null) { - $url_host=parse_url($url, PHP_URL_HOST); - - $http_proxy = $http_proxy_override ?? getenv('http_proxy'); - $no_proxy = $no_proxy_override ?? getenv('no_proxy'); - $no_proxy_arr = ($no_proxy) ? explode (",", $no_proxy) : []; - - // php does not support sock5 proxies in HTTP context options, only http proxies - // do not proxy hosts listed in the no_proxy environment variable - if ($http_proxy && str_starts_with($http_proxy, 'http://') && ! in_array($url_host, $no_proxy_arr)) { - $auth = null; - $proxy_parts = parse_url($http_proxy); - if (isset($proxy_parts['user']) && isset($proxy_parts['pass'])) { - // rebuild $http_proxy url without user:pass - $http_proxy = $proxy_parts['scheme'] . '://' . $proxy_parts['host'] . (isset($proxy_parts['port']) ? ':' . $proxy_parts['port'] : ''); - // prep for basic auth - $auth = base64_encode(urldecode($proxy_parts['user']).':'.urldecode($proxy_parts['pass'])); - } - $http_proxy = str_replace('http://', 'tcp://', $http_proxy); - $streamContextOptions['http']['proxy'] = $http_proxy; - $streamContextOptions['http']['request_fulluri'] = true; - if ($auth) $streamContextOptions['http']['header'] = 'Proxy-Authorization: Basic '.$auth; - } - if (!empty($streamContextOptions)) { - $streamContext=stream_context_create($streamContextOptions); - return $streamContext; - } else { - return null; - } -} ?> diff --git a/emhttp/plugins/dynamix/include/update.wireguard.php b/emhttp/plugins/dynamix/include/update.wireguard.php index 000a6dea6..4c292b059 100644 --- a/emhttp/plugins/dynamix/include/update.wireguard.php +++ b/emhttp/plugins/dynamix/include/update.wireguard.php @@ -21,6 +21,22 @@ if (!isset($_SESSION['locale'])) $_SESSION['locale'] = _var($_POST,'#locale'); require_once "$docroot/webGui/include/Translations.php"; +function download_url($url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 12); + curl_setopt($ch, CURLOPT_TIMEOUT, 45); + curl_setopt($ch, CURLOPT_ENCODING, ""); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_REFERER, ""); + curl_setopt($ch, CURLOPT_FAILONERROR, true); + $out = curl_exec($ch) ?: false; + curl_close($ch); + return $out; +} + $dockerd = is_file('/var/run/dockerd.pid') && is_dir('/proc/'.file_get_contents('/var/run/dockerd.pid')); $etc = '/etc/wireguard'; $validIP4 = "(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})"; @@ -425,13 +441,10 @@ case 'public': $ip = _var($_POST,'#ip'); $v4 = _var($_POST,'#prot')!='6'; $v6 = _var($_POST,'#prot')!=''; - $wanip4url = 'https://wanip4.unraid.net'; - $wanip6url = 'https://wanip6.unraid.net'; - $contextOptions['http']['timeout'] = 12; $int_ipv4 = $v4 ? (preg_match("/^$validIP4$/",$ip) ? $ip : (@dns_get_record($ip,DNS_A)[0]['ip'] ?: '')) : ''; - $ext_ipv4 = $v4 ? (@file_get_contents($wanip4url,false,getProxyStreamContext($wanip4url,$contextOptions)) ?: '') : ''; + $ext_ipv4 = $v4 ? (download_url('https://wanip4.unraid.net') ?: '') : ''; $int_ipv6 = $v6 ? (preg_match("/^$validIP6$/",$ip) ? $ip : (@dns_get_record($ip,DNS_AAAA)[0]['ipv6'] ?: '')) : ''; - $ext_ipv6 = $v6 ? (@file_get_contents($wanip6url,false,getProxyStreamContext($wanip6url,$contextOptions)) ?: '') : ''; + $ext_ipv6 = $v6 ? (download_url('https://wanip6.unraid.net') ?: '') : ''; echo "$int_ipv4;$ext_ipv4;$int_ipv6;$ext_ipv6"; break; case 'addtunnel': From b69564caed3eb4e4084d9e798d03d778b287286b Mon Sep 17 00:00:00 2001 From: ljm42 Date: Tue, 19 Mar 2024 11:56:13 -0700 Subject: [PATCH 6/8] tidy --- emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php | 1 - 1 file changed, 1 deletion(-) diff --git a/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php b/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php index 4c64b6ed4..2e3fb9882 100644 --- a/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php +++ b/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php @@ -29,7 +29,6 @@ */ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); require_once "$docroot/webGui/include/Wrappers.php"; -require_once "$docroot/webGui/include/Helpers.php"; require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php"; class UnraidOsCheck From c6e549ac7df023098438695ea610bb7ffeb3859f Mon Sep 17 00:00:00 2001 From: ljm42 Date: Wed, 20 Mar 2024 13:48:26 -0700 Subject: [PATCH 7/8] Make executable --- sbin/set_proxy | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 sbin/set_proxy diff --git a/sbin/set_proxy b/sbin/set_proxy old mode 100644 new mode 100755 From d68da6a187b859729c244a60a037e977a4ffc717 Mon Sep 17 00:00:00 2001 From: ljm42 Date: Wed, 20 Mar 2024 15:31:59 -0700 Subject: [PATCH 8/8] remove special handling for wget, use environment variables instead --- sbin/set_proxy | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/sbin/set_proxy b/sbin/set_proxy index 3272e01d3..10127f213 100755 --- a/sbin/set_proxy +++ b/sbin/set_proxy @@ -11,7 +11,6 @@ CFG=/boot/config/proxy.cfg # these files are generated by this script based on the data in proxy.cfg PROXY_SH=/etc/profile.d/proxy.sh -WGET=/root/.wgetrc # random file extension for atomic writes RND=$RANDOM @@ -54,28 +53,6 @@ EOF mv "${FILE}.${RND}" "${FILE}" } -# write /root/.wgetrc -set_wget() { - local FILE - FILE="${WGET}" - cat <"${FILE}.${RND}" -# Do not edit. This file is autogenerated by /usr/local/sbin/set_proxy -use_proxy=yes -http_proxy=${proxy_url} -https_proxy=${proxy_url} -no_proxy="${no_proxy}" -EOF - chmod 644 "${FILE}.${RND}" - mv "${FILE}.${RND}" "${FILE}" -} - -# clear /root/.wgetrc -unset_wget() { - local FILE - FILE="${WGET}" - [[ -f "${FILE}" ]] && rm "${FILE}" -} - # restart_phpfpm whenever the environment variables change restart_phpfpm () { /etc/rc.d/rc.php-fpm restart > /dev/null @@ -85,7 +62,6 @@ restart_phpfpm () { add_proxy_to_generated_files_and_exit() { echo "generating proxy files" set_proxy_sh - set_wget . "${PROXY_SH}" restart_phpfpm [[ -n "${VERBOSE}" ]] && display_generated_files @@ -96,7 +72,6 @@ add_proxy_to_generated_files_and_exit() { remove_proxy_from_generated_files_and_exit() { echo "removing proxy info from generated files" unset_proxy_sh - unset_wget . "${PROXY_SH}" restart_phpfpm [[ -n "${VERBOSE}" ]] && display_generated_files @@ -107,7 +82,6 @@ remove_proxy_from_generated_files_and_exit() { display_generated_files() { echo display_generated_file "${PROXY_SH}" - display_generated_file "${WGET}" } # when verbose mode enabled