Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Proxy Support to Unix Install Script #515

Merged
merged 7 commits into from
Jan 3, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion scripts/unix-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ Usage:
If not provided, this will default to Stanza\'s GitHub releases.
Example: '-l http://my.domain.org/stanza' will download from there.

$(fg_yellow '-x, --proxy')
Defines the proxy server to be used for communication by the install script.
Example: $(fg_blue -x) $(fg_magenta http\(s\)://server-ip:port/).

$(fg_yellow '-U, --proxy-user')
Defines the proxy user to be used for communication by the install script.

$(fg_yellow '-P, --proxy-password')
Defines the proxy password to be used for communication by the install script.


EOF
)
info "$USAGE"
Expand Down Expand Up @@ -228,6 +239,7 @@ setup_installation()
set_download_urls
set_install_dir
set_agent_home
set_proxy

# Service variables
set_service_user
Expand Down Expand Up @@ -451,8 +463,20 @@ install_package()
stop_service
succeeded

proxy_args=""
if [ -n "$proxy" ]; then
proxy_args="-x $proxy"
if [ -n "$proxy_user" ]; then
proxy_args="$proxy_args -U $proxy_user:$proxy_password"
fi
fi

if [ -n "$proxy" ]; then
info "Downloading package using proxy..."
fi

info "Downloading binary..."
curl -L "$agent_download_url" -o "$agent_binary" --progress-bar --fail || error_exit "$LINENO" "Failed to download package"
eval curl -L "$proxy_args" "$agent_download_url" -o "$agent_binary" --progress-bar --fail || error_exit "$LINENO" "Failed to download package"
succeeded

info "Setting permissions..."
Expand Down Expand Up @@ -535,6 +559,41 @@ pipeline:
EOF
}

set_proxy()
{
if [ -n "$proxy" ]; then
info "Using proxy from arguments: $proxy"
schmikei marked this conversation as resolved.
Show resolved Hide resolved
if [ -n "$proxy_user" ]; then
while [ -z "$proxy_password" ] && [ ! "$accept_defaults" = "yes" ]; do
increase_indent
command printf "${indent}$(fg_blue "$proxy_user@$proxy")'s password: "
stty -echo
read -r proxy_password
stty echo
info
if [ -z "$proxy_password" ]; then
warn "The password must be provided!"
fi
decrease_indent
done
protocol="$(echo "$proxy" | cut -d'/' -f1)"
host="$(echo "$proxy" | cut -d'/' -f3)"
full_proxy="$protocol//$proxy_user:$proxy_password@$host"
fi

elif [ -n "$http_proxy" ]; then
info "Using proxy from profile: $http_proxy"
proxy="$http_proxy"
elif [ -n "$https_proxy" ]; then
info "Using proxy from profile: $https_proxy"
proxy="$https_proxy"
fi

if [ -z "$full_proxy" ]; then
full_proxy="$proxy"
fi
}

# This will install the service by detecting the init system
# and configuring the launcher to run accordinngly
install_service()
Expand Down Expand Up @@ -1071,6 +1130,12 @@ main()
service_user=$2 ; shift 2 ;;
-l|--url)
url=$2 ; shift 2 ;;
-x|--proxy)
proxy=$2 ; shift 2 ;;
-U|--proxy-user)
proxy_user=$2 ; shift 2 ;;
-P|--proxy-password)
proxy_password=$2 ; shift 2 ;;
-h|--help)
usage
force_exit
Expand Down
210 changes: 209 additions & 1 deletion scripts/windows-install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,27 @@ new-module -name LogAgentInstall -scriptblock {
Show-ColorText 'If not provided, this will default to the current user.' DarkCyan
Remove-Indent

Show-ColorText ''
Show-ColorText '-p, -proxy'
Add-Indent
Show-ColorText 'Defines the proxy server to be used for communication by the install script and used in the configuration for the agent being installed' DarkCyan
Show-ColorText 'If not provided, no proxy will be used' DarkCyan
Remove-Indent

Show-ColorText ''
Show-ColorText '-pu, -proxy_user'
Add-Indent
Show-ColorText 'Defines the proxy user to be used for communication by the install script and used in the configuration for the agent being installed.' DarkCyan
Show-ColorText 'Requires ' '' '-proxy' Magenta
Remove-Indent

Show-ColorText ''
Show-ColorText '-pp, -proxy_password'
Add-Indent
Show-ColorText 'Defines the proxy password to be used for communication by the install script and used in the configuration for the agent being installed.' DarkCyan
Show-ColorText 'Requires ' '' '-proxy' Magenta ' and ' '' '-proxy_user' Magenta
Remove-Indent

Remove-Indent
Remove-Indent
}
Expand Down Expand Up @@ -254,6 +275,149 @@ new-module -name LogAgentInstall -scriptblock {
}
}

# This will set the proxy of the agent. If not provided as a flag,
# it detects if proxy is in environment.
function Set-Proxy {
Show-Header "Configuring Proxy"
Add-Indent

# Check proxy was provided as argument. If not then see if we can detect one in the environment
if($script:proxy){
if ($script:proxy -ilike "http*://*:*@*:*") {
$masked_proxy = Get-MaskedProxy $script:proxy
} else {
$masked_proxy = $script:proxy
}
Show-ColorText 'Using proxy from arguments: ' '' "$masked_proxy" DarkCyan
} else {
Get-Proxy
}

# If a proxy is present then check is proxy_user was provided as an argument.
# If proxy_user exists then proxy_password is required as an argument. Build a URI with user and pass.
if($script:proxy)
{
# Check if proxy contains username and password then parse.
# This will handle username names with email, but it will still fail due to agent download
# using System.Net.WebProxy which doesn't seem to handle that case.
if ($script:proxy -ilike "http*://*:*@*:*") {
$script:full_proxy = $script:proxy
$protocol, $proxy_user_pass_host = $script:proxy -split "://"
$p_user, $pass_host, $port = $proxy_user_pass_host -split ":"
$p_pass, $p_host = $pass_host -split "@"
# Ensure $script:proxy is a full_proxy uri.
# We don't want username and password in URI when we build System.Net.WebProxy for Get-AgentArchive.
$script:proxy = "${protocol}://${p_host}:$port"
# If proxy_user argument wasn't used then use uri username
if (-not ($script:proxy_user)) {
$script:proxy_user = $p_user
}
# If proxy_password argument wasn't used then use uri password
if (-not ($script:proxy_password)) {
$script:proxy_password = $p_pass
}
} elseif ($script:proxy -notlike "http*://*") {
$message = "Argument 'proxy' must include protocol (http:// or https://) in URI."
Exit-Error $MyInvocation.ScriptLineNumber $message
}

if ([string]::IsNullOrWhiteSpace($script:full_proxy)) {
if (-not ([string]::IsNullOrWhiteSpace($script:proxy_user))) {
$protocol, $proxy_host = $script:proxy -split "://"
$script:full_proxy = "${protocol}://$script:proxy_user`:$script:proxy_password@$proxy_host"
} else {
$script:full_proxy = $script:proxy
}
}

# Get $script:http_proxy from environment variable if it exist
if ([string]::IsNullOrWhiteSpace($script:http_proxy)) {
Get-HttpProxy
}
# Get $script:https_proxy from environment variable if it exist
if ( [string]::IsNullOrWhiteSpace($script:https_proxy)) {
Get-HttpsProxy
}
} else {
Show-ColorText "${indent}No existing proxy configuration detected."
}
Remove-Indent
}


# Check if $script:http_proxy has a value if not attempt to fill from existing environment variable
function Get-HttpProxy {
if ([string]::IsNullOrWhiteSpace($script:http_proxy)) {
if ((-not ([string]::IsNullOrWhiteSpace([System.Environment]::GetEnvironmentVariable('HTTP_PROXY','machine')))) -or (-not ([string]::IsNullOrWhiteSpace([System.Environment]::GetEnvironmentVariable('HTTP_PROXY','user'))))) {
$script:http_proxy = [System.Environment]::GetEnvironmentVariable('HTTP_PROXY','user')
if ([string]::IsNullOrWhiteSpace($script:http_proxy)) {
$script:http_proxy = [System.Environment]::GetEnvironmentVariable('HTTP_PROXY','machine')
}
}
}
}

# Check if $script:https_proxy has a value if not attempt to fill from existing environment variable
function Get-HttpsProxy {
if ([string]::IsNullOrWhiteSpace($script:https_proxy)) {
if ((-not ([string]::IsNullOrWhiteSpace([System.Environment]::GetEnvironmentVariable('HTTPS_PROXY','machine')))) -or (-not ([string]::IsNullOrWhiteSpace([System.Environment]::GetEnvironmentVariable('HTTPS_PROXY','user'))))) {
$script:https_proxy = [System.Environment]::GetEnvironmentVariable('HTTPS_PROXY','user')
if ([string]::IsNullOrWhiteSpace($script:https_proxy)) {
$script:https_proxy = [System.Environment]::GetEnvironmentVariable('HTTPS_PROXY','machine')
}
}
}
}

# Check system for an existing proxy configuration.
function Get-Proxy {
Show-ColorText "Searching for existing proxy configuration..."
$proxies = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').proxyServer

if ($proxies)
{
if ($proxies -ilike "*=*")
{
$proxies -replace "=","://" -split(';') | Select-Object -First 1
}

else
{
$proxy = "http://" + $proxies
}
}

if(!$proxies) {
Get-HttpProxy
Get-HttpsProxy
if ($script:http_proxy) {
$proxy = $script:http_proxy
}
if (($script:https_proxy) -ne ($script:http_proxy)) {
$proxy = $script:https_proxy
}
}

if($proxy -ne $script:proxy)
{
$script:proxy = $proxy
if ($script:proxy -ilike "http*://*:*@*:*") {
$masked_proxy = Get-MaskedProxy $script:proxy
} else {
$masked_proxy = $script:proxy
}
Show-ColorText 'Using detected proxy: ' '' "${masked_proxy}" DarkCyan
}
}

# Removes masks username and password out of full proxy string
function Get-MaskedProxy($proxy_to_mask) {
$protocol, $proxy_user_pass_host = $proxy_to_mask -split "://"
$p_user, $pass_host, $port = $proxy_user_pass_host -split ":"
$p_pass, $p_host = $pass_host -split "@"
"${protocol}://<masked_user>:<masked_pass>@${p_host}:${port}"
}

# This will set the install path of the agent. If not provided as a flag,
# the user will be prompted for this information.
function Set-InstallDir {
Expand Down Expand Up @@ -409,10 +573,30 @@ new-module -name LogAgentInstall -scriptblock {
function Get-StanzaBinary {
Show-Header "Downloading Stanza Binary"
Add-Indent
Show-ColorText 'Downloading binary. Please wait...'
if ($script:proxy) {
Show-ColorText "Downloading binary using proxy. Please wait..."
} else {
Show-ColorText 'Downloading binary. Please wait...'
}

Show-ColorText "$INDENT_WIDTH$script:agent_download_url" DarkCyan ' -> ' '' "$script:binary_location" DarkCyan
try {
$WebClient = New-Object System.Net.WebClient
if ($script:proxy) {
$WebProxy = New-Object System.Net.WebProxy($script:proxy)

if ($script:proxy_user) {
if(-not ($script:proxy_password)) {
$message = "Argument 'p' or 'proxy_password' is required when 'proxy_user' argument is specified"
throw [System.ArgumentException]$message
}
$Credentials = New-Object System.Net.NetworkCredential($script:proxy_user, $script:proxy_password)
$Credentials = $Credentials.GetCredential($script:proxy, "Basic");
$WebProxy.Credentials = $Credentials
}

$WebClient.Proxy = $WebProxy
}
$WebClient.DownloadFile($script:agent_download_url, $script:binary_location)
Complete
}
Expand Down Expand Up @@ -578,6 +762,7 @@ pipeline:
Show-Header "Creating Service"
Add-Indent
Install-AgentService
Set-ServiceProxyEnv
Start-AgentService
Complete
Remove-Indent
Expand Down Expand Up @@ -608,6 +793,29 @@ pipeline:
$script:autostart = "Yes"
}


# This will set service specific environment variables.
function Set-ServiceProxyEnv {
if (([string]::IsNullOrWhiteSpace($script:full_proxy)) -or ([string]::IsNullOrWhiteSpace($SERVICE_NAME))) {
return
}
else {
$script:registry_path = "HKLM:\SYSTEM\CurrentControlSet\Services\$SERVICE_NAME"
try {
if (Test-Path $script:registry_path) {
New-ItemProperty -Path "$script:registry_path" -Name 'Environment' -PropertyType 'MultiString' -Force | Out-Null
$item_prop_env = (Get-ItemProperty -Path "$script:registry_path").Environment
$item_prop_env += "HTTP_PROXY=$script:full_proxy"
$item_prop_env += "HTTPS_PROXY=$script:full_proxy"
Set-ItemProperty -Path "$script:registry_path" -Name 'Environment' -Value $item_prop_env -Type 'Multistring'
}
}
catch {
Exit-Error $MyInvocation.ScriptLineNumber "Failed to set Environment property for the $SERVICE_NAME service."
}
}
}

# This will start the agent service.
function Start-AgentService {
Show-ColorText 'Starting service...'
Expand Down