Do not call deprecated datetime.utcnow() and datetime.utcfromtimestamp()
diff --git a/acme/acme/_internal/tests/fields_test.py b/acme/acme/_internal/tests/fields_test.py
index a45bdc47bf0..0c2b8c4a084 100644
--- a/acme/acme/_internal/tests/fields_test.py
+++ b/acme/acme/_internal/tests/fields_test.py
@@ -34,7 +34,7 @@ class RFC3339FieldTest(unittest.TestCase):
     """Tests for acme.fields.RFC3339Field."""
 
     def setUp(self):
-        self.decoded = datetime.datetime(2015, 3, 27, tzinfo=pytz.utc)
+        self.decoded = datetime.datetime(2015, 3, 27, tzinfo=pytz.UTC)
         self.encoded = '2015-03-27T00:00:00Z'
 
     def test_default_encoder(self):
diff --git a/acme/acme/fields.py b/acme/acme/fields.py
index bcd0346d895..2ff5da419aa 100644
--- a/acme/acme/fields.py
+++ b/acme/acme/fields.py
@@ -34,7 +34,7 @@ class RFC3339Field(jose.Field):
 
     Handles decoding/encoding between RFC3339 strings and aware (not
     naive) `datetime.datetime` objects
-    (e.g. ``datetime.datetime.now(pytz.utc)``).
+    (e.g. ``datetime.datetime.now(pytz.UTC)``).
 
     """
 
diff --git a/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py b/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py
index 72520bd8bb7..f01332fedd9 100755
--- a/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py
+++ b/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py
@@ -5,6 +5,7 @@
 """
 import datetime
 import http.server as BaseHTTPServer
+import pytz
 import re
 from typing import cast
 from typing import Union
@@ -54,7 +55,7 @@ def do_POST(self) -> None:
         else:
             data = response.json()
 
-            now = datetime.datetime.utcnow()
+            now = datetime.datetime.now(pytz.UTC)
             cert = x509.load_pem_x509_certificate(data['Certificate'].encode(), default_backend())
             if data['Status'] != 'Revoked':
                 ocsp_status = ocsp.OCSPCertStatus.GOOD
diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md
index 20cc0fb251d..7eae5a0a368 100644
--- a/certbot/CHANGELOG.md
+++ b/certbot/CHANGELOG.md
@@ -17,7 +17,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
 
 ### Fixed
 
-*
+* Do not call deprecated datetime.utcnow() and datetime.utcfromtimestamp()
 
 More details about these changes can be found on our GitHub repo.
 
diff --git a/certbot/certbot/_internal/cert_manager.py b/certbot/certbot/_internal/cert_manager.py
index c7205c30490..0b6115d26d7 100644
--- a/certbot/certbot/_internal/cert_manager.py
+++ b/certbot/certbot/_internal/cert_manager.py
@@ -301,7 +301,7 @@ def human_readable_cert_info(config: configuration.NamespaceConfig, cert: storag
         return None
     if config.domains and not set(config.domains).issubset(cert.names()):
         return None
-    now = pytz.UTC.fromutc(datetime.datetime.utcnow())
+    now = datetime.datetime.now(pytz.UTC)
 
     reasons = []
     if cert.is_test_cert:
diff --git a/certbot/certbot/_internal/storage.py b/certbot/certbot/_internal/storage.py
index 7ddc5e9296c..a535ac3365f 100644
--- a/certbot/certbot/_internal/storage.py
+++ b/certbot/certbot/_internal/storage.py
@@ -1023,7 +1023,7 @@ def should_autorenew(self) -> bool:
             interval = self.configuration.get("renew_before_expiry", default_interval)
             expiry = crypto_util.notAfter(self.version(
                 "cert", self.latest_common_version()))
-            now = pytz.UTC.fromutc(datetime.datetime.utcnow())
+            now = datetime.datetime.now(pytz.UTC)
             if expiry < add_time_interval(now, interval):
                 logger.debug("Should renew, less than %s before certificate "
                              "expiry %s.", interval,
diff --git a/certbot/certbot/_internal/tests/cert_manager_test.py b/certbot/certbot/_internal/tests/cert_manager_test.py
index c8483efa72f..d5e3b2cc5cf 100644
--- a/certbot/certbot/_internal/tests/cert_manager_test.py
+++ b/certbot/certbot/_internal/tests/cert_manager_test.py
@@ -254,7 +254,7 @@ def test_report_human_readable(self, mock_revoked, mock_serial):
         import pytz
 
         from certbot._internal import cert_manager
-        expiry = pytz.UTC.fromutc(datetime.datetime.utcnow())
+        expiry = datetime.datetime.now(pytz.UTC)
 
         cert = mock.MagicMock(lineagename="nameone")
         cert.target_expiry = expiry
diff --git a/certbot/certbot/_internal/tests/main_test.py b/certbot/certbot/_internal/tests/main_test.py
index b2b715ea8ba..c7e8d21676c 100644
--- a/certbot/certbot/_internal/tests/main_test.py
+++ b/certbot/certbot/_internal/tests/main_test.py
@@ -2081,13 +2081,12 @@ class ReportNewCertTest(unittest.TestCase):
     """
 
     def setUp(self):
-        from datetime import datetime
         self.notify_patch = mock.patch('certbot._internal.main.display_util.notify')
         self.mock_notify = self.notify_patch.start()
 
         self.notafter_patch = mock.patch('certbot._internal.main.crypto_util.notAfter')
         self.mock_notafter = self.notafter_patch.start()
-        self.mock_notafter.return_value = datetime.utcfromtimestamp(0)
+        self.mock_notafter.return_value = datetime.datetime(1970, 1, 1, 0, 0)
 
     def tearDown(self):
         self.notify_patch.stop()
diff --git a/certbot/certbot/_internal/tests/ocsp_test.py b/certbot/certbot/_internal/tests/ocsp_test.py
index 0d1404fcb4f..86abf8bf49e 100644
--- a/certbot/certbot/_internal/tests/ocsp_test.py
+++ b/certbot/certbot/_internal/tests/ocsp_test.py
@@ -65,7 +65,7 @@ def test_init(self, mock_exists, mock_run, mock_log):
     @mock.patch('certbot.ocsp.crypto_util.notAfter')
     @mock.patch('certbot.util.run_script')
     def test_ocsp_revoked(self, mock_run, mock_na, mock_determine):
-        now = pytz.UTC.fromutc(datetime.utcnow())
+        now = datetime.now(pytz.UTC)
         cert_obj = mock.MagicMock()
         cert_obj.cert_path = "x"
         cert_obj.chain_path = "y"
@@ -138,7 +138,7 @@ def setUp(self):
         self.cert_obj = mock.MagicMock()
         self.cert_obj.cert_path = self.cert_path
         self.cert_obj.chain_path = self.chain_path
-        now = pytz.UTC.fromutc(datetime.utcnow())
+        now = datetime.now(pytz.UTC)
         self.mock_notAfter = mock.patch('certbot.ocsp.crypto_util.notAfter',
                                         return_value=now + timedelta(hours=2))
         self.mock_notAfter.start()
@@ -324,8 +324,8 @@ def _construct_mock_ocsp_response(certificate_status, response_status):
         responder_name=responder.subject,
         certificates=[responder],
         hash_algorithm=hashes.SHA1(),
-        next_update=datetime.now() + timedelta(days=1),
-        this_update=datetime.now() - timedelta(days=1),
+        next_update=datetime.now(pytz.UTC).replace(tzinfo=None) + timedelta(days=1),
+        this_update=datetime.now(pytz.UTC).replace(tzinfo=None) - timedelta(days=1),
         signature_algorithm_oid=x509.oid.SignatureAlgorithmOID.RSA_WITH_SHA1,
     )
 
diff --git a/certbot/certbot/_internal/tests/storage_test.py b/certbot/certbot/_internal/tests/storage_test.py
index 3b407547803..020a7062aa4 100644
--- a/certbot/certbot/_internal/tests/storage_test.py
+++ b/certbot/certbot/_internal/tests/storage_test.py
@@ -481,8 +481,8 @@ def test_time_interval_judgments(self, mock_datetime, mock_set_by_user):
                 (1420070400, "10 weeks", True), (1420070400, "10 months", True),
                 (1420070400, "10 years", True), (1420070400, "99 months", True),
         ]:
-            sometime = datetime.datetime.utcfromtimestamp(current_time)
-            mock_datetime.datetime.utcnow.return_value = sometime
+            sometime = datetime.datetime.fromtimestamp(current_time, pytz.UTC)
+            mock_datetime.datetime.now.return_value = sometime
             self.test_rc.configuration["renew_before_expiry"] = interval
             assert self.test_rc.should_autorenew() == result
 
@@ -739,10 +739,10 @@ def test_add_time_interval(self):
         from certbot._internal import storage
 
         # this month has 30 days, and the next year is a leap year
-        time_1 = pytz.UTC.fromutc(datetime.datetime(2003, 11, 20, 11, 59, 21))
+        time_1 = datetime.datetime(2003, 11, 20, 11, 59, 21, tzinfo=pytz.UTC)
 
         # this month has 31 days, and the next year is not a leap year
-        time_2 = pytz.UTC.fromutc(datetime.datetime(2012, 10, 18, 21, 31, 16))
+        time_2 = datetime.datetime(2012, 10, 18, 21, 31, 16, tzinfo=pytz.UTC)
 
         # in different time zone (GMT+8)
         time_3 = pytz.timezone('Asia/Shanghai').fromutc(
diff --git a/certbot/certbot/ocsp.py b/certbot/certbot/ocsp.py
index 8f558eb7b5c..a24f04f0da8 100644
--- a/certbot/certbot/ocsp.py
+++ b/certbot/certbot/ocsp.py
@@ -78,7 +78,7 @@ def ocsp_revoked_by_paths(self, cert_path: str, chain_path: str, timeout: int =
         # Let's Encrypt doesn't update OCSP for expired certificates,
         # so don't check OCSP if the cert is expired.
         # https://github.com/certbot/certbot/issues/7152
-        now = pytz.UTC.fromutc(datetime.utcnow())
+        now = datetime.now(pytz.UTC)
         if crypto_util.notAfter(cert_path) <= now:
             return False
 
@@ -233,7 +233,8 @@ def _check_ocsp_response(response_ocsp: 'ocsp.OCSPResponse', request_ocsp: 'ocsp
     #      for OpenSSL, so we do not do it here.
     # See OpenSSL implementation as a reference:
     # https://github.com/openssl/openssl/blob/ef45aa14c5af024fcb8bef1c9007f3d1c115bd85/crypto/ocsp/ocsp_cl.c#L338-L391
-    now = datetime.utcnow()  # thisUpdate/nextUpdate are expressed in UTC/GMT time zone
+    # thisUpdate/nextUpdate are expressed in UTC/GMT time zone
+    now = datetime.now(pytz.UTC).replace(tzinfo=None)
     if not response_ocsp.this_update:
         raise AssertionError('param thisUpdate is not set.')
     if response_ocsp.this_update > now + timedelta(minutes=5):
diff --git a/pytest.ini b/pytest.ini
index 672e2c0542d..8d06655fff4 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -26,7 +26,11 @@
 #    It is also is used in sphinxcontrib-devhelp 1.0.2 which as of writing this
 #    is the latest version of that library. See
 #    https://github.com/sphinx-doc/sphinxcontrib-devhelp/blob/1.0.2/setup.py#L69.
+# 6) Ignore DeprecationWarning from using pkg_resources API
 # 7) Ignore our own PendingDeprecationWarning about Python 3.7 soon to be dropped.
+# 8) Ignore DeprecationWarning for datetime.utcfromtimestamp() triggered
+#    when importing the pytz.tzinfo module
+#    https://github.com/stub42/pytz/issues/105
 filterwarnings =
     error
     ignore:decodestring\(\) is a deprecated alias:DeprecationWarning:dns
@@ -34,4 +38,6 @@ filterwarnings =
     ignore:'urllib3.contrib.pyopenssl:DeprecationWarning:requests_toolbelt
     ignore:update_symlinks is deprecated:PendingDeprecationWarning
     ignore:.*declare_namespace\(':DeprecationWarning
+    ignore:pkg_resources is deprecated as an API:DeprecationWarning:pkg_resources
     ignore:Python 3.7 support will be dropped:PendingDeprecationWarning
+    ignore:datetime.utcfromtimestamp\(\) is deprecated:DeprecationWarning:pytz.tzinfo

With Python 3.12:

~~~
# python3
Python 3.12.0b4 (main, Jul 12 2023, 00:00:00) [GCC 13.1.1 20230614 (Red Hat 13.1.1-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> datetime.datetime.utcnow()
<stdin>:1: DeprecationWarning: datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.now(datetime.UTC).
datetime.datetime(2023, 7, 15, 23, 20, 12, 672120)
>>> datetime.datetime.utcfromtimestamp(0)
<stdin>:1: DeprecationWarning: datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.fromtimestamp(timestamp, datetime.UTC).
datetime.datetime(1970, 1, 1, 0, 0)
~~~

## Pull Request Checklist

- [ ] The Certbot team has recently expressed interest in reviewing a PR for this. If not, this PR may be closed due our limited resources and need to prioritize how we spend them.
- [x] If the change being made is to a [distributed component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), edit the `master` section of `certbot/CHANGELOG.md` to include a description of the change being made.
- [ ] Add or update any documentation as needed to support the changes in this PR.
- [ ] Include your name in `AUTHORS.md` if you like.
