mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-09 03:04:54 -04:00
fix: log accurate IP (#2416)
* update dev docker poetry install * Forward/Report IP through front and backend. * Add fail2ban docs * fix option name and iproute2 in omni entry * Fix entry scripts -> gunicorn setting respected * gunicorn off * xfwd in nuxt proxy and handle multiple IPs
This commit is contained in:
parent
5e904d19b4
commit
9557b3f0b6
@ -26,7 +26,7 @@ ENV PYTHONUNBUFFERED=1 \
|
|||||||
# prepend poetry and venv to path
|
# prepend poetry and venv to path
|
||||||
ENV PATH="$POETRY_HOME/bin:$PATH"
|
ENV PATH="$POETRY_HOME/bin:$PATH"
|
||||||
|
|
||||||
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python -
|
RUN curl -sSL https://install.python-poetry.org | python3 -
|
||||||
# RUN poetry config virtualenvs.create false
|
# RUN poetry config virtualenvs.create false
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
|
@ -71,6 +71,7 @@ ENV GIT_COMMIT_HASH=$COMMIT
|
|||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install --no-install-recommends -y \
|
&& apt-get install --no-install-recommends -y \
|
||||||
gosu \
|
gosu \
|
||||||
|
iproute2 \
|
||||||
tesseract-ocr-all \
|
tesseract-ocr-all \
|
||||||
libldap-2.4-2 \
|
libldap-2.4-2 \
|
||||||
&& apt-get autoremove \
|
&& apt-get autoremove \
|
||||||
|
@ -50,10 +50,10 @@ init
|
|||||||
GUNICORN_PORT=${API_PORT:-9000}
|
GUNICORN_PORT=${API_PORT:-9000}
|
||||||
|
|
||||||
# Start API
|
# Start API
|
||||||
|
hostip=`/sbin/ip route|awk '/default/ { print $3 }'`
|
||||||
if [ "$WEB_GUNICORN" == 'true' ]; then
|
if [ "$WEB_GUNICORN" = 'true' ]; then
|
||||||
echo "Starting Gunicorn"
|
echo "Starting Gunicorn"
|
||||||
gunicorn mealie.app:app -b 0.0.0.0:$GUNICORN_PORT -k uvicorn.workers.UvicornWorker -c /app/gunicorn_conf.py --preload
|
gunicorn mealie.app:app -b 0.0.0.0:$GUNICORN_PORT --forwarded-allow-ips=$hostip -k uvicorn.workers.UvicornWorker -c /app/gunicorn_conf.py --preload
|
||||||
else
|
else
|
||||||
uvicorn mealie.app:app --host 0.0.0.0 --port $GUNICORN_PORT
|
uvicorn mealie.app:app --host 0.0.0.0 --forwarded-allow-ips=$hostip --port $GUNICORN_PORT
|
||||||
fi
|
fi
|
||||||
|
@ -64,11 +64,10 @@ services:
|
|||||||
|
|
||||||
# =====================================
|
# =====================================
|
||||||
# Web Concurrency
|
# Web Concurrency
|
||||||
WEB_GUNICORN: "true"
|
WEB_GUNICORN: "false"
|
||||||
WORKERS_PER_CORE: 0.5
|
WORKERS_PER_CORE: 0.5
|
||||||
MAX_WORKERS: 1
|
MAX_WORKERS: 1
|
||||||
WEB_CONCURRENCY: 1
|
WEB_CONCURRENCY: 1
|
||||||
|
|
||||||
# =====================================
|
# =====================================
|
||||||
# Email Configuration
|
# Email Configuration
|
||||||
# SMTP_HOST=
|
# SMTP_HOST=
|
||||||
@ -79,13 +78,13 @@ services:
|
|||||||
# SMTP_USER=
|
# SMTP_USER=
|
||||||
# SMTP_PASSWORD=
|
# SMTP_PASSWORD=
|
||||||
|
|
||||||
# postgres:
|
# postgres:
|
||||||
# container_name: postgres
|
# container_name: postgres
|
||||||
# image: postgres
|
# image: postgres
|
||||||
# restart: always
|
# restart: always
|
||||||
# environment:
|
# environment:
|
||||||
# POSTGRES_PASSWORD: mealie
|
# POSTGRES_PASSWORD: mealie
|
||||||
# POSTGRES_USER: mealie
|
# POSTGRES_USER: mealie
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
mealie-data:
|
mealie-data:
|
||||||
|
@ -94,6 +94,7 @@ ENV GIT_COMMIT_HASH=$COMMIT
|
|||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install --no-install-recommends -y \
|
&& apt-get install --no-install-recommends -y \
|
||||||
gosu \
|
gosu \
|
||||||
|
iproute2 \
|
||||||
tesseract-ocr-all \
|
tesseract-ocr-all \
|
||||||
curl \
|
curl \
|
||||||
gnupg \
|
gnupg \
|
||||||
|
@ -26,11 +26,10 @@ services:
|
|||||||
|
|
||||||
# =====================================
|
# =====================================
|
||||||
# Web Concurrency
|
# Web Concurrency
|
||||||
WEB_GUNICORN: true
|
WEB_GUNICORN: "false"
|
||||||
WORKERS_PER_CORE: 0.5
|
WORKERS_PER_CORE: 0.5
|
||||||
MAX_WORKERS: 1
|
MAX_WORKERS: 1
|
||||||
WEB_CONCURRENCY: 1
|
WEB_CONCURRENCY: 1
|
||||||
|
|
||||||
# =====================================
|
# =====================================
|
||||||
# Email Configuration
|
# Email Configuration
|
||||||
# SMTP_HOST=
|
# SMTP_HOST=
|
||||||
|
@ -46,12 +46,12 @@ init
|
|||||||
GUNICORN_PORT=${API_PORT:-9000}
|
GUNICORN_PORT=${API_PORT:-9000}
|
||||||
|
|
||||||
# Start API
|
# Start API
|
||||||
|
hostip=`/sbin/ip route|awk '/default/ { print $3 }'`
|
||||||
if [ "$WEB_GUNICORN" == 'true' ]; then
|
if [ "$WEB_GUNICORN" = 'true' ]; then
|
||||||
echo "Starting Gunicorn"
|
echo "Starting Gunicorn"
|
||||||
gunicorn mealie.app:app -b 0.0.0.0:$GUNICORN_PORT -k uvicorn.workers.UvicornWorker -c /app/gunicorn_conf.py --preload &
|
gunicorn mealie.app:app -b 0.0.0.0:$GUNICORN_PORT --forwarded-allow-ips=$hostip -k uvicorn.workers.UvicornWorker -c /app/gunicorn_conf.py --preload &
|
||||||
else
|
else
|
||||||
uvicorn mealie.app:app --host 0.0.0.0 --port $GUNICORN_PORT &
|
uvicorn mealie.app:app --host 0.0.0.0 --forwarded-allow-ips=$hostip --port $GUNICORN_PORT &
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
@ -132,6 +132,15 @@ stateDiagram-v2
|
|||||||
p3 --> n1: No
|
p3 --> n1: No
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Can I use fail2ban with mealie?
|
||||||
|
Yes, mealie is configured to properly forward external IP addresses into the `mealie.log` logfile. Note that, due to restrictions in docker, IP address forwarding only works on linux.
|
||||||
|
|
||||||
|
Your fail2ban usage should look like the following:
|
||||||
|
```
|
||||||
|
Use datepattern : %d-%b-%y %H:%M:%S : Day-MON-Year2 24hour:Minute:Second
|
||||||
|
Use failregex line : ^ERROR:\s+Incorrect username or password from <HOST>
|
||||||
|
```
|
||||||
|
|
||||||
## Why An API?
|
## Why An API?
|
||||||
An API allows integration into applications like [Home Assistant](https://www.home-assistant.io/) that can act as notification engines to provide custom notifications based of Meal Plan data to remind you to defrost the chicken, marinade the steak, or start the CrockPot. Additionally, you can access nearly any backend service via the API giving you total control to extend the application. To explore the API spin up your server and navigate to http://yourserver.com/docs for interactive API documentation.
|
An API allows integration into applications like [Home Assistant](https://www.home-assistant.io/) that can act as notification engines to provide custom notifications based of Meal Plan data to remind you to defrost the chicken, marinade the steak, or start the CrockPot. Additionally, you can access nearly any backend service via the API giving you total control to extend the application. To explore the API spin up your server and navigate to http://yourserver.com/docs for interactive API documentation.
|
||||||
|
|
||||||
|
@ -295,10 +295,12 @@ export default {
|
|||||||
},
|
},
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
target: process.env.API_URL || "http://localhost:9000",
|
target: process.env.API_URL || "http://localhost:9000",
|
||||||
|
xfwd: true,
|
||||||
},
|
},
|
||||||
"/api": {
|
"/api": {
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
target: process.env.API_URL || "http://localhost:9000",
|
target: process.env.API_URL || "http://localhost:9000",
|
||||||
|
xfwd: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -52,15 +52,21 @@ class MealieAuthToken(BaseModel):
|
|||||||
def get_token(request: Request, data: CustomOAuth2Form = Depends(), session: Session = Depends(generate_session)):
|
def get_token(request: Request, data: CustomOAuth2Form = Depends(), session: Session = Depends(generate_session)):
|
||||||
email = data.username
|
email = data.username
|
||||||
password = data.password
|
password = data.password
|
||||||
|
if "x-forwarded-for" in request.headers:
|
||||||
|
ip = request.headers["x-forwarded-for"]
|
||||||
|
if "," in ip: # if there are multiple IPs, the first one is canonically the true client
|
||||||
|
ip = str(ip.split(",")[0])
|
||||||
|
else:
|
||||||
|
ip = request.client.host
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = authenticate_user(session, email, password) # type: ignore
|
user = authenticate_user(session, email, password) # type: ignore
|
||||||
except UserLockedOut as e:
|
except UserLockedOut as e:
|
||||||
logger.error(f"User is locked out from {request.client.host}")
|
logger.error(f"User is locked out from {ip}")
|
||||||
raise HTTPException(status_code=status.HTTP_423_LOCKED, detail="User is locked out") from e
|
raise HTTPException(status_code=status.HTTP_423_LOCKED, detail="User is locked out") from e
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
logger.error(f"Incorrect username or password from {request.client.host}")
|
logger.error(f"Incorrect username or password from {ip}")
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user