mirror of
https://github.com/telemt/telemt.git
synced 2026-10-11 11:55:59 +03:00
Secure + VersionD Outbound Paddings Fix
This commit is contained in:
@@ -226,8 +226,9 @@ fn iptables_reject_args() -> Vec<String> {
|
||||
]
|
||||
}
|
||||
|
||||
pub(super) async fn clear_rules_for_binary(binary: &str) -> Result<(), String> {
|
||||
pub(super) async fn clear_rules_for_binary(binary: &str) -> Result<bool, String> {
|
||||
let mut errors = Vec::new();
|
||||
let mut removed = false;
|
||||
for _ in 0..8 {
|
||||
match run_command(
|
||||
binary,
|
||||
@@ -236,7 +237,9 @@ pub(super) async fn clear_rules_for_binary(binary: &str) -> Result<(), String> {
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(()) => {}
|
||||
Ok(()) => {
|
||||
removed = true;
|
||||
}
|
||||
Err(error) if is_missing_command_or_iptables_rule(&error) => break,
|
||||
Err(error) => {
|
||||
errors.push(format!("{binary} delete INPUT jump failed: {error}"));
|
||||
@@ -244,19 +247,27 @@ pub(super) async fn clear_rules_for_binary(binary: &str) -> Result<(), String> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Err(error) = run_command(binary, &["-t", "filter", "-F", IPTABLES_CHAIN], None).await
|
||||
&& !is_missing_command_or_iptables_rule(&error)
|
||||
{
|
||||
errors.push(format!("{binary} flush chain failed: {error}"));
|
||||
match run_command(binary, &["-t", "filter", "-F", IPTABLES_CHAIN], None).await {
|
||||
Ok(()) => {
|
||||
removed = true;
|
||||
}
|
||||
Err(error) if is_missing_command_or_iptables_rule(&error) => {}
|
||||
Err(error) => {
|
||||
errors.push(format!("{binary} flush chain failed: {error}"));
|
||||
}
|
||||
}
|
||||
if let Err(error) = run_command(binary, &["-t", "filter", "-X", IPTABLES_CHAIN], None).await
|
||||
&& !is_missing_command_or_iptables_rule(&error)
|
||||
{
|
||||
errors.push(format!("{binary} delete chain failed: {error}"));
|
||||
match run_command(binary, &["-t", "filter", "-X", IPTABLES_CHAIN], None).await {
|
||||
Ok(()) => {
|
||||
removed = true;
|
||||
}
|
||||
Err(error) if is_missing_command_or_iptables_rule(&error) => {}
|
||||
Err(error) => {
|
||||
errors.push(format!("{binary} delete chain failed: {error}"));
|
||||
}
|
||||
}
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
Ok(removed)
|
||||
} else {
|
||||
Err(errors.join(", "))
|
||||
}
|
||||
@@ -266,6 +277,7 @@ fn is_missing_command_or_iptables_rule(error: &str) -> bool {
|
||||
error.contains("is not available")
|
||||
|| error.contains("No chain/target/match by that name")
|
||||
|| error.contains("does not exist")
|
||||
|| error.contains("Couldn't load target")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
+33
-11
@@ -39,8 +39,14 @@ async fn wait_for_config_channel_close_and_reconcile(
|
||||
}
|
||||
|
||||
pub(crate) async fn reconcile_synlimit_rules(cfg: &ProxyConfig) {
|
||||
if let Err(error) = clear_synlimit_rules_all_backends().await {
|
||||
warn!(error = %error, "Failed to clear existing SYN limiter rules before reconcile");
|
||||
match clear_synlimit_rules_all_backends().await {
|
||||
Ok(true) => {
|
||||
warn!("Removed stale SYN limiter rules left by a previous run before reconcile");
|
||||
}
|
||||
Ok(false) => {}
|
||||
Err(error) => {
|
||||
warn!(error = %error, "Failed to clear stale SYN limiter rules before reconcile");
|
||||
}
|
||||
}
|
||||
|
||||
let targets = synlimit_targets(cfg);
|
||||
@@ -66,24 +72,40 @@ pub(crate) async fn reconcile_synlimit_rules(cfg: &ProxyConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn clear_synlimit_rules_all_backends() -> Result<(), String> {
|
||||
pub(crate) async fn clear_synlimit_rules_all_backends() -> Result<bool, String> {
|
||||
if !has_cap_net_admin() {
|
||||
return Ok(());
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let mut errors = Vec::new();
|
||||
if let Err(error) = nftables::clear_rules_all_families().await {
|
||||
errors.push(error);
|
||||
let mut removed = false;
|
||||
match nftables::clear_rules_all_families().await {
|
||||
Ok(value) => {
|
||||
removed |= value;
|
||||
}
|
||||
Err(error) => {
|
||||
errors.push(error);
|
||||
}
|
||||
}
|
||||
if let Err(error) = iptables::clear_rules_for_binary("iptables").await {
|
||||
errors.push(error);
|
||||
match iptables::clear_rules_for_binary("iptables").await {
|
||||
Ok(value) => {
|
||||
removed |= value;
|
||||
}
|
||||
Err(error) => {
|
||||
errors.push(error);
|
||||
}
|
||||
}
|
||||
if let Err(error) = iptables::clear_rules_for_binary("ip6tables").await {
|
||||
errors.push(error);
|
||||
match iptables::clear_rules_for_binary("ip6tables").await {
|
||||
Ok(value) => {
|
||||
removed |= value;
|
||||
}
|
||||
Err(error) => {
|
||||
errors.push(error);
|
||||
}
|
||||
}
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
Ok(removed)
|
||||
} else {
|
||||
Err(errors.join("; "))
|
||||
}
|
||||
|
||||
@@ -186,26 +186,32 @@ fn push_nft_v6_rules(script: &mut String, target: &SynLimitRule, idx: usize) {
|
||||
));
|
||||
}
|
||||
|
||||
pub(super) async fn clear_rules_all_families() -> Result<(), String> {
|
||||
pub(super) async fn clear_rules_all_families() -> Result<bool, String> {
|
||||
let mut errors = Vec::new();
|
||||
let mut removed = false;
|
||||
for family in [NftFamily::Inet, NftFamily::Ip, NftFamily::Ip6] {
|
||||
if let Err(error) = run_command(
|
||||
match run_command(
|
||||
"nft",
|
||||
&["delete", "table", family.as_str(), NFT_TABLE],
|
||||
None,
|
||||
)
|
||||
.await
|
||||
&& !is_missing_command_or_nft_table(&error)
|
||||
{
|
||||
errors.push(format!(
|
||||
"nft delete table {} {NFT_TABLE} failed: {error}",
|
||||
family.as_str()
|
||||
));
|
||||
Ok(()) => {
|
||||
removed = true;
|
||||
}
|
||||
Err(error) if is_missing_command_or_nft_table(&error) => {}
|
||||
Err(error) => {
|
||||
errors.push(format!(
|
||||
"nft delete table {} {NFT_TABLE} failed: {error}",
|
||||
family.as_str()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
Ok(removed)
|
||||
} else {
|
||||
Err(errors.join(", "))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user