Initial commit

This commit is contained in:
Sean Lawlor
2022-10-28 06:12:10 -07:00
commit 267044cb6f
28 changed files with 1321 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
name: CI
on:
push:
branches: [ "main" ]
pull_request:
types: [opened, reopened, synchronize]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
with:
# ct needs history to compare
fetch-depth: 0
- name: Build the Docker image
run: docker build ./proxy/ --tag whatsapp_proxy:$(date +%s)
- name: Set up Helm
uses: azure/setup-helm@v3
with:
version: v3.10.0
- uses: actions/setup-python@v4
with:
python-version: '3.9'
check-latest: true
- name: Helm - Set up chart-testing
uses: helm/chart-testing-action@v2.3.1
- name: Helm - Run chart-testing (list-changed)
id: list-changed
run: |
changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }})
if [[ -n "$changed" ]]; then
echo "::set-output name=changed::true"
fi
- name: Helm - Run chart-testing (lint)
run: ct lint --target-branch ${{ github.event.repository.default_branch }}
+39
View File
@@ -0,0 +1,39 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
name: Publish
on:
push:
tags:
- 'v*.*.*'
jobs:
publish:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
# The :11 strips the first 11 characters from the environment variable GITHUB_REF which contains refs/tags/v1.2.3 so it yields 1.2.3
- name: Set release version (i.e. tag)
id: vars
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/v}
- name: Print the release version (i.e. tag)
run: echo "TAG = ${{ steps.vars.outputs.tag }}"
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v3
with:
context: ./proxy
push: true
tags: seanlawlor/whatsapp_proxy:${{ steps.vars.outputs.tag }}
+2
View File
@@ -0,0 +1,2 @@
tmp/
helm/whatsapp-proxy-chart*.tgz
+80
View File
@@ -0,0 +1,80 @@
<!-- Copyright (c) Meta Platforms, Inc. and affiliates.
License found in the LICENSE file in the root directory
of this source tree. -->
# Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <opensource-conduct@fb.com>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
+34
View File
@@ -0,0 +1,34 @@
<!-- Copyright (c) Meta Platforms, Inc. and affiliates.
License found in the LICENSE file in the root directory
of this source tree. -->
# Contributing to this library
We want to make contributing to this project as easy and transparent as
possible.
## Pull Requests
We actively welcome your pull requests.
1. Fork the repo and create your branch from `main`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes.
5. If you haven't already, complete the Contributor License Agreement ("CLA").
## Contributor License Agreement ("CLA")
In order to accept your pull request, we need you to submit a CLA. You only need
to do this once to work on any of Facebook's open source projects.
Complete your CLA here: <https://code.facebook.com/cla>
## Issues
We use GitHub issues to track public bugs. Please ensure your description is
clear and has sufficient instructions to be able to reproduce the issue.
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
disclosure of security bugs. In those cases, please go through the process
outlined on that page and do not file a public issue.
## License
By contributing to akd, you agree that your contributions will be
licensed under the LICENSE file in the root directory of this source tree.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Meta Platforms, Inc. and affiliates.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+137
View File
@@ -0,0 +1,137 @@
<!-- Copyright (c) Meta Platforms, Inc. and affiliates.
License found in the LICENSE file in the root directory
of this source tree. -->
# WhatsApp Chat Proxy
[<img alt="github" src="https://img.shields.io/badge/github-WhatsApp/proxy-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/WhatsApp/proxy)
[<img alt="build status" src="https://img.shields.io/github/workflow/status/WhatsApp/proxy/ci/main?style=for-the-badge" height="20">](https://github.com/WhatsApp/proxy/actions?query=branch%3Amain)
This project aims to provide an open-proxy implementation based on [HAProxy](https://www.haproxy.org/) which allows users to proxy their mobile apps through a central hub in the event they are unable to contact WhatsApp directly.
**Current Version**: 1.0
## Setup and Installation
This section outlines a basic setup and configuration for the proxy container which supports upwards of 27K connections concurrently.
### Dependencies
1. [Docker](https://docs.docker.com/engine/install/)
2. [optional] [Docker compose](https://docs.docker.com/compose/)
3. [optional] Enable docker on startup (host system dependent)
If your version of docker doesn't come pre-installed with Docker compose, you can install a one-off version with (for Linux)
```bash
# Download the pkg
sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose
# Enable execution of the script
sudo chmod +x /usr/bin/docker-compose
```
### Building
You can build the proxy host container with
```bash
docker build /path/to/git/repo/ -t whatsapp_proxy:1.0
```
which will compile the container and tag it as `whatsapp_proxy:1.0` for easy reference.
### Running
You can manually execute the docker container with the following docker command
```bash
docker run -it -p 80:80 -p 443:443 -p 5222:5222 -p 8080:8080 -p 8443:8443 -p 8222:8222 -p 8199:8199 whatsapp_proxy:1.0
```
however normally you don't want to manually run the container except for testing scenarios. Therefore we recommend utilizing Docker compose which
is a helpful automation tool to manage setting up the container and necessary port forwards, etc without user interaction.
#### Automate the container lifecycle with Docker Compose
Docker compose is a tool to run multi-container deployments, but also helps automate the command-line arguments necessary to run a single container. It is a YAML definition file which denotes all of the settings to startup and run the container as well as restart strategies in the event the container crashes or self-restarts.
We provide a sample [docker-compose.yml](./proxy/ops/docker-compose.yml) file for you which defines a standard deployment of the proxy container. Once docker compose is installed, you can test your specific configuration by running docker compose interactively with
```bash
docker compose -f /path/to/this/repo/docker-compose.yml up
```
which will allow you to see the output from the build + container hosting process to identify if everything is setup correctly. When you are ready to run the container as a service, do
```bash
docker compose -f /path/to/this/repo/docker-compose.yml up -d
```
Note the `-d` flag which means "daemonize" and run as a service. To stop the container you can similarly do
```bash
docker compose down
```
Once you have a docker compose setup, you can also automate the deployment for host reboots by utilizing a `systemd` service (if your hosting environment supports it). We provide a sample [`docker_boot.service`](./proxy/ops/docker_boot.service) service definition for you which you should customize to your own environment. To install and setup the `systemd` service you can do the following
```bash
# Copy the service definition to systemd folder
cp -v docker_boot.service /etc/systemd/system/
# Enable starting the service on startup
systemctl enable docker_boot.service
# Start the service (will docker compose up the container)
systemctl start docker_boot.service
# Check container status with
docker ps
```
**NOTE:** Make sure to update the path to your specific `docker-compose.yml` file in the service definition `docker_boot.service`!
## Kubernetes deployment
See [Helm chart README](./charts/README.md)
# Architecture Overview
The provided proxy container exposes multiple ports depending on scenarios you may with to utilize for proxying. The basic ports are
1. 80: Standard web traffic (HTTP)
2. 443: Standard web traffic, encrypted (HTTPS)
3. 5222: Jabber protocol traffic (WhatsApp default)
There are also ports configured which accept incoming [proxy headers](https://www.haproxy.com/blog/use-the-proxy-protocol-to-preserve-a-clients-ip-address/) (version 1 or 2)
on connections, such that if you have some kind of network load balancer or something you can preserve the client ip address should you wish.
1. 8080: Standard web traffic (HTTP) with PROXY protocol expected
2. 8443: Standard web traffic, encrypted (HTTPS) with PROXY protocol expected
3. 8222: Jabber protocol traffic (WhatsApp default) with PROXY protocol expected
Additionally the container exposes a stats port on `:8199` which can be connected to directly with `http://<host-ip>:8199` which you can monitor
HAProxy statistics.
## Certificate generation for SSL encrypted ports
Ports 443 and 8443 are protected by a self-signed encryption certificate generated at container build time. There are some custom options should you wish to tweak the settings of the generated certificates
* `SSL_DNS` comma seperate list of alternative hostnames, no default
* `SSL_IP` comma seperate list of alternative IPs, no default
They can be set with commands like
```bash
docker build . --build-arg SSL_DNS=test.example.com
```
# Contributors
------------
The authors of this code are
* Sean Lawlor ([@slawlor](https://github.com/slawlor)).
To learn more about contributing to this project, [see this document](https://github.com/whatsapp/proxy/blob/main/CONTRIBUTING.md).
# License
-------
This project is licensed under [MIT](https://github.com/novifinancial/akd/blob/main/LICENSE-MIT).
+50
View File
@@ -0,0 +1,50 @@
<!-- Copyright (c) Meta Platforms, Inc. and affiliates.
License found in the LICENSE file in the root directory
of this source tree. -->
# WhatsApp Proxy Helm Charts
This guide outlines how to utilize the [Helm chart](https://helm.sh/) for whatsapp-proxy in order to run the proxy in a [kubernetes](https://kubernetes.io/) cluster.
**NOTE**: This is quite an advanced topic and requires general knowledge around kubernetes and deployments of containers in distributed infrastructure. A healthy knowledge of kubernetes is required to deploy this.
[<img alt="github" src="https://img.shields.io/badge/github-WhatsApp/proxy-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/WhatsApp/proxy)
[<img alt="build status" src="https://img.shields.io/github/workflow/status/WhatsApp/proxy/ci/main?style=for-the-badge" height="20">](https://github.com/WhatsApp/proxy/actions?query=branch%3Amain)
## Before you begin
### Setup a Kubernetes Cluster
The quickest way to setup a Kubernetes cluster is with [Azure Kubernetes Service](https://azure.microsoft.com/en-us/services/kubernetes-service/), [AWS Elastic Kubernetes Service](https://aws.amazon.com/eks/) or [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) using their respective quick-start guides.
For setting up Kubernetes on other cloud platforms or bare-metal servers refer to the Kubernetes [getting started guide](http://kubernetes.io/docs/getting-started-guides/).
### Install Helm
Get the latest [Helm release](https://github.com/helm/helm#install).
### Add Helm chart repo
Once you have Helm installed, add the repo as follows:
**TBD**
<!-- ```console
helm repo add whatsapp_proxy https://WhatsApp.github.io/proxy
helm repo update
``` -->
WhatsApp Proxy Helm charts can be also found on [ArtifactHub](https://artifacthub.io/packages/search?repo=WhatsApp).
## Search and install charts
```console
helm search repo WhatsApp/
helm install my-release WhatsApp/<chart>
```
**_NOTE_**: For instructions on how to install a chart follow instructions in its `README.md`.
## Contributing
We welcome all contributions. Please refer to [guidelines](../CONTRIBUTING.md) on how to make a contribution.
+36
View File
@@ -0,0 +1,36 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
apiVersion: v1
kind: Service
metadata:
name: whatsapp-proxy-lb-1
annotations:
service.beta.kubernetes.io/do-loadbalancer-name: "whatsapp-proxy-lb-1"
service.beta.kubernetes.io/do-loadbalancer-size-unit: "100"
service.beta.kubernetes.io/do-loadbalancer-disable-lets-encrypt-dns-records: "true"
service.beta.kubernetes.io/do-loadbalancer-healthcheck-port: "80"
service.beta.kubernetes.io/do-loadbalancer-healthcheck-protocol: "tcp"
service.beta.kubernetes.io/do-loadbalancer-healthcheck-check-interval-seconds: "30"
service.beta.kubernetes.io/do-loadbalancer-healthcheck-response-timeout-seconds: "5"
service.beta.kubernetes.io/do-loadbalancer-healthcheck-unhealthy-threshold: "2"
service.beta.kubernetes.io/do-loadbalancer-healthcheck-healthy-threshold: "5"
service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "true"
spec:
type: LoadBalancer
selector:
app: whatsapp-proxy
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8443
- name: jabber
protocol: TCP
port: 5222
targetPort: 8222
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.5 KiB

+26
View File
@@ -0,0 +1,26 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
apiVersion: v2
name: whatsapp-proxy-chart
description: A Helm chart for Kubernetes for the WhatsApp Proxy infrastructure
icon: https://github.com/whatsapp/proxy/blob/main/helm/wa_logo.svc
maintainers:
- name: slawlor
email: seanlawlor@meta.com
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"
@@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "whatsapp-proxy-chart.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "whatsapp-proxy-chart.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "whatsapp-proxy-chart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "whatsapp-proxy-chart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
@@ -0,0 +1,69 @@
{{/*
Copyright (c) Meta Platforms, Inc. and affiliates.
License found in the LICENSE file in the root directory
of this source tree.
*/}}
{{/*
Expand the name of the chart.
*/}}
{{- define "whatsapp-proxy-chart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "whatsapp-proxy-chart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "whatsapp-proxy-chart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "whatsapp-proxy-chart.labels" -}}
helm.sh/chart: {{ include "whatsapp-proxy-chart.chart" . }}
{{ include "whatsapp-proxy-chart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "whatsapp-proxy-chart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "whatsapp-proxy-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "whatsapp-proxy-chart.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "whatsapp-proxy-chart.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
@@ -0,0 +1,98 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "whatsapp-proxy-chart.fullname" . }}
labels:
{{- include "whatsapp-proxy-chart.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "whatsapp-proxy-chart.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "whatsapp-proxy-chart.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "whatsapp-proxy-chart.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
{{- if .Values.service.http_proxy_port }}
- name: http-proxy
containerPort: 8080
protocol: TCP
{{- end}}
{{- if .Values.service.http_port }}
- name: http
containerPort: 80
protocol: TCP
{{- end}}
{{- if .Values.service.https_proxy_port }}
- name: https-proxy
containerPort: 8443
protocol: TCP
{{- end}}
{{- if .Values.service.https_port }}
- name: https
containerPort: 443
protocol: TCP
{{- end}}
{{- if .Values.service.jabber_proxy_port }}
- name: jabber-proxy
containerPort: 8222
protocol: TCP
{{- end}}
{{- if .Values.service.jabber_port }}
- name: jabber
containerPort: 5222
protocol: TCP
{{- end}}
{{- if .Values.service.stats_port }}
- name: stats
containerPort: 8199
protocol: TCP
{{- end}}
readinessProbe:
exec:
command:
- /usr/local/bin/healthcheck.sh
initialDelaySeconds: 30
periodSeconds: 30
resources:
{{- toYaml .Values.resources | nindent 12 }}
env:
- name: "PUBLIC_IP"
value: "{{ .Values.public_ip }}"
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
@@ -0,0 +1,32 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "whatsapp-proxy-chart.fullname" . }}
labels:
{{- include "whatsapp-proxy-chart.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "whatsapp-proxy-chart.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}
@@ -0,0 +1,65 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "whatsapp-proxy-chart.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "whatsapp-proxy-chart.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,58 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
apiVersion: v1
kind: Service
metadata:
name: {{ include "whatsapp-proxy-chart.fullname" . }}
labels:
{{- include "whatsapp-proxy-chart.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
{{- if .Values.service.http_proxy_port }}
- port: {{ .Values.service.http_proxy_port }}
targetPort: 8080
protocol: TCP
name: http-proxy
{{- end}}
{{- if .Values.service.https_proxy_port }}
- port: {{ .Values.service.https_proxy_port }}
targetPort: 8443
protocol: TCP
name: https-proxy
{{- end}}
{{- if .Values.service.jabber_proxy_port }}
- port: {{ .Values.service.jabber_proxy_port }}
targetPort: 8222
protocol: TCP
name: jabber-proxy
{{- end}}
{{- if .Values.service.jabber_port }}
- port: {{ .Values.service.jabber_port }}
targetPort: 5222
protocol: TCP
name: jabber
{{- end}}
{{- if .Values.service.http_port }}
- port: {{ .Values.service.http_port }}
targetPort: 80
protocol: TCP
name: http
{{- end}}
{{- if .Values.service.https_port }}
- port: {{ .Values.service.https_port }}
targetPort: 443
protocol: TCP
name: http
{{- end}}
{{- if .Values.service.stats_port }}
- port: {{ .Values.service.stats_port }}
targetPort: {{ .Values.service.stats_port }}
protocol: TCP
name: stats
{{- end}}
selector:
{{- include "whatsapp-proxy-chart.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,16 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "whatsapp-proxy-chart.serviceAccountName" . }}
labels:
{{- include "whatsapp-proxy-chart.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,19 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "whatsapp-proxy-chart.fullname" . }}-test-connection"
labels:
{{- include "whatsapp-proxy-chart.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "whatsapp-proxy-chart.fullname" . }}:{{ .Values.service.stats_port }}']
restartPolicy: Never
+95
View File
@@ -0,0 +1,95 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
# Default values for whatsapp-proxy-chart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 10
image:
repository: seanlawlor/whatsapp_proxy
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "1.0"
public_ip: "10.0.0.1"
imagePullSecrets: {}
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "whatsapp-proxy"
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
# http_port: 80
# https_port: 443
# jabber_port: 5222
http_proxy_port: 8080
https_proxy_port: 8443
jabber_proxy_port: 8222
# stats_port: 8199
ingress:
enabled: false
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: waprox.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
+6
View File
@@ -0,0 +1,6 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
ops/
+56
View File
@@ -0,0 +1,56 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
FROM haproxy:lts-alpine
# Install dependencies for healthcheck support
USER root
RUN apk --update --no-cache add curl openssl jq bash
# Customization variables for certificate generation
ARG SSL_IP
ARG SSL_DNS
# Generate + copy the self-signed certificate settings
WORKDIR /certs
COPY src/generate-certs.sh /usr/local/bin/generate-certs.sh
RUN chmod +x /usr/local/bin/generate-certs.sh && \
/usr/local/bin/generate-certs.sh && \
mkdir --parents /etc/haproxy/ssl/ && \
mv /certs/proxy.whatsapp.net.pem /etc/haproxy/ssl/proxy.whatsapp.net.pem && \
chown -R haproxy:haproxy /etc/haproxy/
WORKDIR /
# Copy the public-ip setting + sshd startup script
COPY --chown=haproxy:haproxy src/set_public_ip_and_start.sh /usr/local/bin/set_public_ip_and_start.sh
RUN chmod +x /usr/local/bin/set_public_ip_and_start.sh
# Copy the HAProxy configuration
COPY --chown=haproxy:haproxy src/proxy_config.cfg /usr/local/etc/haproxy/haproxy.cfg
RUN chown haproxy:haproxy /usr/local/etc/haproxy
# Copy + define the healthcheck
COPY src/healthcheck.sh /usr/local/bin/healthcheck.sh
RUN chmod +x /usr/local/bin/healthcheck.sh
HEALTHCHECK --interval=10s --start-period=5s CMD bash /usr/local/bin/healthcheck.sh
RUN mkdir --parents /home/haproxy/certs && chown haproxy:haproxy /home/haproxy/certs
# Validate the HAProxy configuration file (sanity check)
RUN haproxy -c -V -f /usr/local/etc/haproxy/haproxy.cfg
# Revert to the haproxy user for runtime operation
USER haproxy
# Expose the container-supported network ports
EXPOSE 80/tcp
EXPOSE 8080/tcp
EXPOSE 443/tcp
EXPOSE 8443/tcp
EXPOSE 5222/tcp
EXPOSE 8222/tcp
EXPOSE 8199/tcp
# This is the startup command which also runs a background job to manage the WAPOX IPs
CMD /usr/local/bin/set_public_ip_and_start.sh
+25
View File
@@ -0,0 +1,25 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
version: '3.3'
services:
proxy:
container_name: whatsapp_proxy
build: ../
restart: unless-stopped
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "5222:5222" # JABBER
- "8199:8199" # HAPROXY statistics page
- "8080:8080" # HTTP with accept-proxy processing
- "8443:8443" # HTTPS with accept-proxy processing
- "8222:8222" # JABBER with accept-proxy processing
healthcheck:
test: /usr/local/bin/healthcheck.sh
interval: 10s
start_period: 5s
environment:
- PUBLIC_IP=10.0.0.1
+19
View File
@@ -0,0 +1,19 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
## Systemd definition for an example service to startup the proxy container on host reboot
[Unit]
description=docker boot
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/root/wa
ExecStart=docker compose -f /root/whatsapp_proxy/docker-compose.yml up -d
[Install]
WantedBy=multi-user.target
+95
View File
@@ -0,0 +1,95 @@
#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
echo "----------------------------"
echo "| SSL Cert Generator |"
echo "----------------------------"
echo
export CA_KEY="ca-key.pem"
export CA_CERT="ca.pem"
export CA_SUBJECT="whatsapp.selfsigned"
export CA_EXPIRE="36500" # 100 years
export SSL_CONFIG="openssl.cnf"
export SSL_KEY="key.pem"
export SSL_CSR="key.csr"
export SSL_CERT="cert.pem"
export SSL_SIZE="2048"
export SSL_EXPIRE="3650" # 10 years
export SSL_SUBJECT="proxy.whatsapp.net"
export SSL_DNS=${SSL_DNS}
export SSL_IP=${SSL_IP}
export DEBUG=${DEBUG:=1}
echo "--> Certificate Authority"
if [[ -e ./${CA_KEY} ]]; then
echo "====> Using existing CA Key ${CA_KEY}"
else
echo "====> Generating new CA key ${CA_KEY}"
openssl genrsa -out ${CA_KEY} 2048
fi
if [[ -e ./${CA_CERT} ]]; then
echo "====> Using existing CA Certificate ${CA_CERT}"
else
echo "====> Generating new CA Certificate ${CA_CERT}"
openssl req -x509 -new -nodes -key ${CA_KEY} -days ${CA_EXPIRE} -out ${CA_CERT} -subj "/CN=${CA_SUBJECT}" || exit 1
fi
[[ -n $DEBUG ]] && cat $CA_CERT
echo "====> Generating new config file ${SSL_CONFIG}"
cat > ${SSL_CONFIG} <<EOM
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
EOM
if [[ -n ${SSL_DNS} || -n ${SSL_IP} ]]; then
cat >> ${SSL_CONFIG} <<EOM
subjectAltName = @alt_names
[alt_names]
EOM
IFS=","
dns=(${SSL_DNS})
dns+=(${SSL_SUBJECT})
for i in "${!dns[@]}"; do
echo DNS.$((i+1)) = ${dns[$i]} >> ${SSL_CONFIG}
done
if [[ -n ${SSL_IP} ]]; then
ip=(${SSL_IP})
for i in "${!ip[@]}"; do
echo IP.$((i+1)) = ${ip[$i]} >> ${SSL_CONFIG}
done
fi
fi
echo "====> Generating new SSL KEY ${SSL_KEY}"
openssl genrsa -out ${SSL_KEY} ${SSL_SIZE} || exit 1
echo "====> Generating new SSL CSR ${SSL_CSR}"
openssl req -new -key ${SSL_KEY} -out ${SSL_CSR} -subj "/CN=${SSL_SUBJECT}" -config ${SSL_CONFIG} || exit 1
echo "====> Generating new SSL CERT ${SSL_CERT}"
openssl x509 -req -in ${SSL_CSR} -CA ${CA_CERT} -CAkey ${CA_KEY} -CAcreateserial -out ${SSL_CERT} \
-days ${SSL_EXPIRE} -extensions v3_req -extfile ${SSL_CONFIG} || exit 1
echo "====> Generating SSL CERT / KEY COMBO proxy.whatsapp.net.pem"
cat ${SSL_KEY} > proxy.whatsapp.net.pem
cat ${SSL_CERT} >> proxy.whatsapp.net.pem
echo "Certificate generation completed."
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
curl -s -w 2 "http://127.0.0.1:8199/;csv" > /tmp/stats.txt || exit 1
# First trim off the leading line which is just "#"
# Then convert the ugly CSV to slightly less ugly JSON
# Filter out the lines for g_whatsapp_net backend status
# Select the "check_desc" field (Description of the check result)
# and take all results that do NOT equal "Layer4 check passed" from HAProxy
RESULT=$(tail -n +1 /tmp/stats.txt | jq -R 'split(",")' | jq -c '. | select(.[1] | contains("g_whatsapp_net"))' | jq --raw-output '.[65]| select(. | test("Layer4 check passed") | not)')
# # CSV output header row:
# # ["# pxname","svname","qcur","qmax","scur","smax","slim","stot","bin","bout","dreq","dresp","ereq","econ","eresp","wretr","wredis","status","weight","act","bck","chkfail","chkdown","lastchg","downtime","qlimit","pid","iid","sid","throttle","lbtot","tracked","type","rate","rate_lim","rate_max","check_status","check_code","check_duration","hrsp_1xx","hrsp_2xx","hrsp_3xx","hrsp_4xx","hrsp_5xx","hrsp_other","hanafail","req_rate","req_rate_max","req_tot","cli_abrt","srv_abrt","comp_in","comp_out","comp_byp","comp_rsp","lastsess","last_chk","last_agt","qtime","ctime","rtime","ttime","agent_status","agent_code","agent_duration","check_desc","agent_desc","check_rise","check_fall","check_health","agent_rise","agent_fall","agent_health","addr","cookie","mode","algo","conn_rate","conn_rate_max","conn_tot","intercepted","dcon","dses","wrew","connect","reuse","cache_lookups","cache_hits","srv_icur","src_ilim","qtime_max","ctime_max","rtime_max","ttime_max","eint","idle_conn_cur","safe_conn_cur","used_conn_cur","need_conn_est","uweight","agg_server_check_status","-","ssl_sess","ssl_reused_sess","ssl_failed_handshake","h2_headers_rcvd","h2_data_rcvd","h2_settings_rcvd","h2_rst_stream_rcvd","h2_goaway_rcvd","h2_detected_conn_protocol_errors","h2_detected_strm_protocol_errors","h2_rst_stream_resp","h2_goaway_resp","h2_open_connections","h2_backend_open_streams","h2_total_connections","h2_backend_total_streams",""]
if [ "$RESULT" != "" ]
then
echo "[HEALTHCHECKER] Container failed healthchecks, L4 healthcheck on g.whatsapp.net failed"
echo "[HEALTKCHECKER] Result $RESULT"
exit -1;
fi
exit 0;
+88
View File
@@ -0,0 +1,88 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
## This file contains the HAProxy configuration for the WhatsApp proxy host use-case
# Documentation
# https://cbonte.github.io/haproxy-dconv/2.5/configuration.html#maxconn
global
# Default buffer size is 16kB and we need 2 buffers/conn.
# For WA we want a lower memory footprint, so we lower it to 4kB.
tune.bufsize 4096
# We limit the connection count to 27.5K connections concurrently such that
# to fail healthchecks we'd have to actually have health problems rather than just reject connections
#
# Upon the 27501'th connection on a proxy port, it'll be REJECTED in favor of reconnecting to a different proxy host
# which will mean the existing connection will be serviced without the host being recycled
maxconn 27500
# Adds some randomness on the interval delay between two consecutive health checks
spread-checks 5
# # Log to local rsyslogd (levels: emerg alert crit err warning notice info debug)
# log 127.0.0.1 local0 notice
ssl-server-verify none
# ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
# ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
# ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
# ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
defaults
mode tcp
# we don't retain this information for long since connections are load balanced they'll end up on a new host
timeout client-fin 1s
timeout server-fin 1s
timeout connect 5s
timeout client 200s
timeout server 200s
log global
option tcplog
default-server inter 10s fastinter 1s downinter 3s error-limit 50
listen stats
bind :::8199
mode http
stats uri /
# These expect direct connections from clients or through NLB balanced
# connections
frontend haproxy_v4_http
maxconn 27495
#PUBLIC_IP
bind ipv4@*:80
bind ipv4@*:8080 accept-proxy
default_backend wa_http
frontend haproxy_v4_https
maxconn 27495
#PUBLIC_IP
bind ipv4@*:443 ssl crt /etc/haproxy/ssl/proxy.whatsapp.net.pem
bind ipv4@*:8443 ssl crt /etc/haproxy/ssl/proxy.whatsapp.net.pem accept-proxy
default_backend wa
frontend haproxy_v4_xmpp
maxconn 27495
#PUBLIC_IP
bind ipv4@*:5222
bind ipv4@*:8222 accept-proxy
default_backend wa
backend wa
default-server check inter 60000 observe layer4 send-proxy
server g_whatsapp_net_5222 g.whatsapp.net:5222
backend wa_http
default-server check inter 60000 observe layer4 send-proxy
server g_whatsapp_net_80 g.whatsapp.net:80
+54
View File
@@ -0,0 +1,54 @@
#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# License found in the LICENSE file in the root directory
# of this source tree.
## About:
# This script replaces instances of #PUBLIC_IP in the HaProxy configuration files
# with the the real public ip. There's an order of priority here which is
# 1. Environment variable
# 2. AWS EC2 Metadata endpoint
#
# If all fails, we'll just not set the destination IP address
CONFIG_FILE="/usr/local/etc/haproxy/haproxy.cfg"
## PUBLIC_IP supplied from environment variable
if [[ $PUBLIC_IP == '' ]]
then
echo "[PROXYHOST] No public IP address was supplied as an environment variable."
fi
## PUBLIC_IP retrieved from AWS EC2 metadata endpoint
if [[ $PUBLIC_IP == '' ]]
then
# Attempt retrieval of the public ip from the meta-data instance
PUBLIC_IP=$(curl --max-time 2 -s http://169.254.169.254/latest/meta-data/public-ipv4)
if [[ $PUBLIC_IP == '' ]]
then
echo "[PROXYHOST] Failed to retrieve public ip address from AWS URI within 2s"
fi
fi
# Now if the public IP is available (test is for not-empty)
# then replace the instances in all haproxy config lines
if [[ ! -z "$PUBLIC_IP" ]]
then
echo "[PROXYHOST] Public IP address ($PUBLIC_IP) in-place replacement occurring on $CONFIG_FILE"
# Replace all instances of #PUBLIC_IP with the
# haproxy configuration statement for the frontend which set's the destination
# ip to the public ip of the container (which is necessary to determine our IP's
# internally within WA)
sed -i "s/#PUBLIC\_IP/tcp-request connection set-dst ipv4($PUBLIC_IP)/g" $CONFIG_FILE
fi
# Setup a new, on-the-fly certificate for the HTTPS port (so this re-generates each restart)
pushd /home/haproxy/certs
/usr/local/bin/generate-certs.sh
mv proxy.whatsapp.net.pem /etc/haproxy/ssl/proxy.whatsapp.net.pem
chown haproxy:haproxy /etc/haproxy/ssl/proxy.whatsapp.net.pem
popd
# Start HAProxy
haproxy -f "$CONFIG_FILE"