Skip to content

Commit

Permalink
Create ipmon-server
Browse files Browse the repository at this point in the history
  • Loading branch information
psidex committed Jul 21, 2023
1 parent 6fb3a3e commit 2300014
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 14 deletions.
17 changes: 14 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- '**.rs'
- 'cargo.toml'
- 'Dockerfile'
- 'Dockerfile.*'
- '.dockerignore'
- '.github/workflows/*.yml'

Expand All @@ -28,20 +29,30 @@ jobs:
uses: docker/setup-buildx-action@v2
with:
platforms: |
linux/arm64
linux/amd64,linux/arm64
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push
- name: Build and push ipmon
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
file: ./Dockerfile.client
push: true
tags: psidex/ipmon:latest
platforms: |
linux/arm64
- name: Build and push ipmon-server
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile.server
push: true
tags: psidex/ipmon-server:latest
platforms: |
linux/amd64
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ edition = "2021"
reqwest = { version = "0.11", features = ["blocking"] }
log = "0.4"
simple_logger = "4.0"
axum = "0.6"
tokio = { version = "1.16.1", features = ["full"] }
4 changes: 2 additions & 2 deletions Dockerfile → Dockerfile.client
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
FROM rust:1.66 as build
FROM rust:1.71 as build
RUN apt update && apt upgrade -y
RUN apt install -y g++-aarch64-linux-gnu libc6-dev-arm64-cross
WORKDIR /ipmon
COPY . .
RUN cargo build --release
RUN cargo build --bin ipmon --release

FROM debian:bullseye-slim
RUN apt update && apt -y install ca-certificates && rm -rf /var/lib/apt/lists/*
Expand Down
9 changes: 9 additions & 0 deletions Dockerfile.server
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM rust:1.71 as build
WORKDIR /ipmon
COPY . .
RUN cargo build --bin ipmon-server --release

FROM debian:bullseye-slim
WORKDIR /app
COPY --from=build /ipmon/target/release/ipmon-server ./
ENTRYPOINT ["/app/ipmon-server"]
28 changes: 28 additions & 0 deletions src/bin/ipmon-server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::net::SocketAddr;

use axum::{extract::ConnectInfo, http::header::HeaderMap, routing::get, Router};

#[tokio::main]
async fn main() {
simple_logger::init_with_level(log::Level::Info).unwrap();

// build our application with a route
let app = Router::new().route("/", get(handler));

axum::Server::bind(&"127.0.0.1:8080".parse().unwrap())
.serve(app.into_make_service_with_connect_info::<SocketAddr>())
.await
.unwrap();
}

async fn handler(headers: HeaderMap, ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
let client_ip;
if headers.contains_key("X-Real-Ip") {
client_ip = headers["X-Real-Ip"].to_str().unwrap().to_owned();
} else if headers.contains_key("X-Forwarded-For") {
client_ip = headers["X-Forwarded-For"].to_str().unwrap().to_owned();
} else {
client_ip = addr.to_string();
}
client_ip
}
31 changes: 24 additions & 7 deletions src/main.rs → src/bin/ipmon.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
use std::str::FromStr;
use std::{env, fs};
use std::{error::Error, net::Ipv4Addr};

use log::info;
use simple_logger;

mod twilio;
use ipmon::platform;
use ipmon::twilio;

const IP_CACHE_PATH: &str = "./ipmon.cache";
const SLEEP_TIME_SECONDS: u64 = 60;

fn get_current_ipv4() -> Result<Ipv4Addr, Box<dyn Error>> {
let get = reqwest::blocking::get("https://api.ipify.org/")?;
Ok(get.text()?.parse::<Ipv4Addr>()?)
let get = reqwest::blocking::get("https://checkip.amazonaws.com/")?;
let ip = match platform::is_debug() {
true => Ipv4Addr::from_str("127.0.0.1")?,
false => get.text()?.parse::<Ipv4Addr>()?,
};
Ok(ip)
}

fn nice_secret(secret: &String) -> String {
Expand All @@ -27,21 +32,33 @@ fn nice_secret(secret: &String) -> String {

fn process(
client: &twilio::Client,
to: &String,
to: &str,
prev_ip: Ipv4Addr,
) -> Result<Ipv4Addr, Box<dyn Error>> {
let addr = get_current_ipv4()?;

if addr != prev_ip {
info!("New IPv4: {}", addr);
client.send_text(to, &format!("Can I have a new IP please, {}", addr))?;
fs::write(IP_CACHE_PATH, &addr.to_string())?;

if !platform::is_debug() {
client.send_text(to, &format!("Can I have a new IP please, {}", addr))?;
} else {
info!("Would send: \"Can I have a new IP please, {}\"", addr);
}

fs::write(IP_CACHE_PATH, addr.to_string())?;
}

Ok(addr)
}

fn main() -> Result<(), Box<dyn Error>> {
simple_logger::init_with_level(log::Level::Info).unwrap();

if platform::is_debug() {
info!("Running in debug mode, won't use APIs")
}

let mut prev_ip = fs::read_to_string(IP_CACHE_PATH)
.unwrap_or("127.0.0.1".to_string())
.parse::<Ipv4Addr>()
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod platform;
pub mod twilio;
3 changes: 3 additions & 0 deletions src/platform.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn is_debug() -> bool {
cfg!(debug_assertions)
}
6 changes: 4 additions & 2 deletions src/twilio.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::error::Error;

pub struct Client {
client: reqwest::blocking::Client,
sid: String,
token: String,
from: String,
Expand All @@ -9,11 +10,13 @@ pub struct Client {

impl Client {
pub fn new(sid: String, token: String, from: String) -> Client {
let client = reqwest::blocking::Client::new();
let url = format!(
"https://api.twilio.com/2010-04-01/Accounts/{}/Messages.json",
sid
);
Client {
client,
sid,
token,
from,
Expand All @@ -22,9 +25,8 @@ impl Client {
}

pub fn send_text(&self, to: &str, message: &str) -> Result<(), Box<dyn Error>> {
let client = reqwest::blocking::Client::new();
let form = [("To", to), ("From", &self.from), ("Body", message)];
client
self.client
.post(&self.url)
.basic_auth(&self.sid, Some(&self.token))
.header("Content-Type", "application/x-www-form-urlencoded")
Expand Down

0 comments on commit 2300014

Please sign in to comment.