Add a system to restrict untrusted IPs
This commit is contained in:
parent
4c839eb2d1
commit
c7f7bfe67c
@ -1,6 +1,8 @@
|
|||||||
use crate::libvirt_lib_structures::XMLUuid;
|
use crate::libvirt_lib_structures::XMLUuid;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use std::net::IpAddr;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
/// VirtWeb backend API
|
/// VirtWeb backend API
|
||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
@ -85,6 +87,11 @@ pub struct AppConfig {
|
|||||||
/// Hypervisor URI. If not specified, "" will be used instead
|
/// Hypervisor URI. If not specified, "" will be used instead
|
||||||
#[arg(long, env)]
|
#[arg(long, env)]
|
||||||
pub hypervisor_uri: Option<String>,
|
pub hypervisor_uri: Option<String>,
|
||||||
|
|
||||||
|
/// Trusted network. If set, a client from a different will not be able to perform request other
|
||||||
|
/// than those with GET verb (aside for login)
|
||||||
|
#[arg(long, env)]
|
||||||
|
pub trusted_network: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
@ -131,6 +138,23 @@ impl AppConfig {
|
|||||||
self.auth_username == user && self.auth_password == pass
|
self.auth_username == user && self.auth_password == pass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if an IP belongs to a trusted network or not
|
||||||
|
pub fn is_trusted_ip(&self, ip: IpAddr) -> bool {
|
||||||
|
if self.trusted_network.is_empty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in &self.trusted_network {
|
||||||
|
let net = ipnetwork::IpNetwork::from_str(i).expect("Trusted network is invalid!");
|
||||||
|
|
||||||
|
if net.contains(ip) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Get OpenID providers configuration
|
/// Get OpenID providers configuration
|
||||||
pub fn openid_provider(&self) -> Option<OIDCProvider<'_>> {
|
pub fn openid_provider(&self) -> Option<OIDCProvider<'_>> {
|
||||||
if self.disable_oidc {
|
if self.disable_oidc {
|
||||||
|
@ -61,6 +61,11 @@ where
|
|||||||
let service = Rc::clone(&self.service);
|
let service = Rc::clone(&self.service);
|
||||||
|
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
|
let remote_ip =
|
||||||
|
actix_remote_ip::RemoteIP::from_request(req.request(), &mut Payload::None)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let auth_disabled = AppConfig::get().unsecure_disable_auth;
|
let auth_disabled = AppConfig::get().unsecure_disable_auth;
|
||||||
|
|
||||||
// Check authentication, if required
|
// Check authentication, if required
|
||||||
@ -89,6 +94,15 @@ where
|
|||||||
)
|
)
|
||||||
.map_into_right_body());
|
.map_into_right_body());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !AppConfig::get().is_trusted_ip(remote_ip.0) && !req.method().as_str().eq("GET")
|
||||||
|
{
|
||||||
|
return Ok(req
|
||||||
|
.into_response(
|
||||||
|
HttpResponse::MethodNotAllowed().json("I am sorry, but your IP is not trusted. You cannot perform this action!"),
|
||||||
|
)
|
||||||
|
.map_into_right_body());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
service
|
service
|
||||||
|
@ -223,7 +223,7 @@ function IsoFilesList(p: {
|
|||||||
p.onReload();
|
p.onReload();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
alert("Failed to delete file!");
|
alert(`Failed to delete file!\n${e}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingMessage.hide();
|
loadingMessage.hide();
|
||||||
|
@ -57,7 +57,7 @@ export function NetworksListRoute(): React.ReactElement {
|
|||||||
snackbar("The network was successfully deleted!");
|
snackbar("The network was successfully deleted!");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
alert("Failed to delete the network!");
|
alert(`Failed to delete the network!\n${e}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import { VMStatusWidget } from "../widgets/vms/VMStatusWidget";
|
|||||||
import { useSnackbar } from "../hooks/providers/SnackbarProvider";
|
import { useSnackbar } from "../hooks/providers/SnackbarProvider";
|
||||||
import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
|
import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useAlert } from "../hooks/providers/AlertDialogProvider";
|
||||||
|
|
||||||
export function VMListRoute(): React.ReactElement {
|
export function VMListRoute(): React.ReactElement {
|
||||||
const [list, setList] = React.useState<VMInfo[] | undefined>();
|
const [list, setList] = React.useState<VMInfo[] | undefined>();
|
||||||
@ -66,6 +67,7 @@ function VMListWidget(p: {
|
|||||||
onReload: () => void;
|
onReload: () => void;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
const confirm = useConfirm();
|
const confirm = useConfirm();
|
||||||
|
const alert = useAlert();
|
||||||
const snackbar = useSnackbar();
|
const snackbar = useSnackbar();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@ -93,7 +95,7 @@ function VMListWidget(p: {
|
|||||||
p.onReload();
|
p.onReload();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
snackbar("Failed to delete VM!");
|
alert(`Failed to delete VM!\n${e}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user