diff --git a/Cargo.lock b/Cargo.lock
index 3d535bc..6ce265d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -739,12 +739,6 @@ version = "0.2.146"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
 
-[[package]]
-name = "linked-hash-map"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
-
 [[package]]
 name = "linux-raw-sys"
 version = "0.3.8"
@@ -1307,14 +1301,15 @@ dependencies = [
 
 [[package]]
 name = "serde_yaml"
-version = "0.8.26"
+version = "0.9.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
+checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c"
 dependencies = [
  "indexmap",
+ "itoa",
  "ryu",
  "serde",
- "yaml-rust",
+ "unsafe-libyaml",
 ]
 
 [[package]]
@@ -1714,6 +1709,12 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
 
+[[package]]
+name = "unsafe-libyaml"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6"
+
 [[package]]
 name = "untrusted"
 version = "0.7.1"
@@ -1966,15 +1967,6 @@ dependencies = [
  "memchr",
 ]
 
-[[package]]
-name = "yaml-rust"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
-dependencies = [
- "linked-hash-map",
-]
-
 [[package]]
 name = "yansi"
 version = "0.5.1"
diff --git a/Cargo.toml b/Cargo.toml
index b7396f9..0ede3e3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,7 +25,7 @@ run_script = "0.9"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 serde_regex = "1.1"
-serde_yaml = "0.8"
+serde_yaml = "0.9"
 sha2 = "0.10"
 thiserror = "1.0"
 
diff --git a/src/config.rs b/src/config.rs
index 64b0eb4..dd69358 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,4 +1,4 @@
-use crate::{filters::IpFilter, hooks::Hook};
+use crate::{filters::IpFilterWrapper, hooks::Hook};
 use anyhow::{bail, Result};
 use log::info;
 use serde::{Deserialize, Serialize};
@@ -8,13 +8,14 @@ use std::{collections::BTreeMap, fs::File};
 #[serde(deny_unknown_fields)]
 pub struct MetricsConfig {
     pub enabled: bool,
-    pub ip_filter: Option<IpFilter>,
+    pub ip_filter: Option<IpFilterWrapper>,
 }
 
 #[derive(Debug, Deserialize, Serialize)]
 #[serde(deny_unknown_fields)]
 pub struct Config {
     pub metrics: Option<MetricsConfig>,
+    #[serde(with = "serde_yaml::with::singleton_map_recursive")]
     pub hooks: BTreeMap<String, Hook>,
 }
 
diff --git a/src/filters.rs b/src/filters.rs
index dc74864..22982f2 100644
--- a/src/filters.rs
+++ b/src/filters.rs
@@ -39,6 +39,14 @@ impl IpFilter {
     }
 }
 
+// FIXME: As `serde_yaml` `0.9` fucks things up, for now this ugly
+// wrapper is needed.
+#[derive(Debug, Deserialize, Serialize)]
+#[serde(transparent)]
+pub struct IpFilterWrapper(
+    #[serde(with = "serde_yaml::with::singleton_map_recursive")] pub IpFilter,
+);
+
 #[derive(Debug, Deserialize, Serialize)]
 pub struct HeaderFilter {
     pub field: String,
diff --git a/src/hooks.rs b/src/hooks.rs
index b653b00..df90461 100644
--- a/src/hooks.rs
+++ b/src/hooks.rs
@@ -1,5 +1,5 @@
 use crate::{
-    filters::{FilterType, IpFilter},
+    filters::{FilterType, IpFilter, IpFilterWrapper},
     Config, Metrics, WebhookeyError,
 };
 use anyhow::{anyhow, bail, Result};
@@ -53,7 +53,7 @@ fn validate_request(secret: &str, signature: &str, data: &[u8]) -> Result<()> {
 pub struct Hook {
     command: String,
     signature: String,
-    ip_filter: Option<IpFilter>,
+    ip_filter: Option<IpFilterWrapper>,
     secrets: Vec<String>,
     filter: FilterType,
 }
@@ -160,7 +160,7 @@ impl Hooks {
 
         let hooks = config.hooks.iter().filter(|(name, hook)| {
             if let Some(ip) = &hook.ip_filter {
-                accept_ip(name, client_ip, ip)
+                accept_ip(name, client_ip, &ip.0)
             } else {
                 info!(
                     "Allow hook `{}` from {}, no IP filter was configured",
@@ -718,9 +718,9 @@ hooks:
                             command: "/usr/bin/local/script_xy.sh {{ /field2/foo }} asdfasdf"
                                 .to_string(),
                             signature: "X-Gitea-Signature".to_string(),
-                            ip_filter: Some(IpFilter::Allow(vec![AddrType::IpNet(
-                                "127.0.0.1/31".parse().unwrap()
-                            )])),
+                            ip_filter: Some(IpFilterWrapper(IpFilter::Allow(vec![
+                                AddrType::IpNet("127.0.0.1/31".parse().unwrap())
+                            ]))),
                             secrets: vec!["secret_key_01".to_string(), "secret_key_02".to_string()],
                             filter: FilterType::JsonFilter(JsonFilter {
                                 pointer: "/ref".to_string(),
@@ -787,9 +787,9 @@ hooks:
                         command: "/usr/bin/local/script_xy.sh {{ /field2/foo }} asdfasdf"
                             .to_string(),
                         signature: "X-Gitea-Signature".to_string(),
-                        ip_filter: Some(IpFilter::Allow(vec![AddrType::IpNet(
+                        ip_filter: Some(IpFilterWrapper(IpFilter::Allow(vec![AddrType::IpNet(
                             "127.0.0.1/31".parse().unwrap()
-                        )])),
+                        )]))),
                         secrets: vec!["secret_key_01".to_string(), "secret_key_02".to_string()],
                         filter: FilterType::JsonFilter(JsonFilter {
                             pointer: "/ref".to_string(),
diff --git a/src/metrics.rs b/src/metrics.rs
index 71c4fae..e7b2a3f 100644
--- a/src/metrics.rs
+++ b/src/metrics.rs
@@ -32,7 +32,7 @@ pub async fn metrics(
             // Is a filter configured?
             if let Some(filter) = &metrics_config.ip_filter {
                 // Does the request match the filter?
-                if filter.validate(&address.ip()) {
+                if filter.0.validate(&address.ip()) {
                     return Some(metrics.get_metrics());
                 }
             } else {