· 3 months ago · Jul 01, 2025, 08:25 AM
1#include <ESP8266WiFi.h>
2#include <ESP8266WebServerSecure.h>
3#include "certs.h"
4#include <map>
5
6const char* ssid = "YOUR_WIFI_SSID";
7const char* password = "YOUR_WIFI_PASSWORD";
8
9const char* authUser = "admin";
10const char* authPass = "yourpassword";
11
12// HTTPS server on port 443
13BearSSL::ESP8266WebServerSecure server(443);
14
15// --- Login Tracking ---
16struct LoginAttempt {
17 uint8_t failedAttempts = 0;
18 unsigned long lastAttemptTime = 0;
19 unsigned long lockoutUntil = 0;
20};
21
22std::map<IPAddress, LoginAttempt> loginMap;
23
24const unsigned int MAX_TRACKED_IPS = 50;
25const unsigned long LOGIN_COOLDOWN = 1000; // 1 second
26const unsigned long LOCKOUT_DURATION = 5 * 60 * 1000; // 5 minutes
27
28void pruneOldestIPIfNeeded() {
29 if (loginMap.size() < MAX_TRACKED_IPS) return;
30
31 IPAddress oldestIP;
32 unsigned long oldestTime = ULONG_MAX;
33
34 for (const auto& entry : loginMap) {
35 if (entry.second.lastAttemptTime < oldestTime) {
36 oldestTime = entry.second.lastAttemptTime;
37 oldestIP = entry.first;
38 }
39 }
40
41 if (oldestTime != ULONG_MAX) {
42 loginMap.erase(oldestIP);
43 Serial.print("Pruned oldest IP: ");
44 Serial.println(oldestIP);
45 }
46}
47
48void setup() {
49 Serial.begin(115200);
50 delay(100);
51
52 WiFi.begin(ssid, password);
53 Serial.print("Connecting to WiFi");
54 while (WiFi.status() != WL_CONNECTED) {
55 delay(500);
56 Serial.print(".");
57 }
58
59 Serial.println("\nWiFi connected. IP address:");
60 Serial.println(WiFi.localIP());
61
62 // Load certificate
63 server.getServer().setRSACert(
64 (const uint8_t*)cert, strlen(cert),
65 (const uint8_t*)key, strlen(key)
66 );
67
68 // Secure route with login protection
69 server.on("/", []() {
70 IPAddress clientIP = server.client().remoteIP();
71 unsigned long now = millis();
72
73 // Prune if this is a new IP
74 if (loginMap.find(clientIP) == loginMap.end()) {
75 pruneOldestIPIfNeeded();
76 }
77
78 LoginAttempt& attempt = loginMap[clientIP];
79
80 if (now - attempt.lastAttemptTime < LOGIN_COOLDOWN) {
81 server.send(429, "text/plain", "Too many requests. Wait a moment.");
82 return;
83 }
84
85 attempt.lastAttemptTime = now;
86
87 if (now < attempt.lockoutUntil) {
88 server.send(403, "text/plain", "Too many failed attempts. Try again later.");
89 return;
90 }
91
92 if (!server.authenticate(authUser, authPass)) {
93 attempt.failedAttempts++;
94
95 if (attempt.failedAttempts >= 3) {
96 attempt.lockoutUntil = now + LOCKOUT_DURATION;
97 server.send(403, "text/plain", "Locked for 5 minutes.");
98 } else {
99 server.requestAuthentication(); // 401 Unauthorized
100 }
101
102 return;
103 }
104
105 // Success
106 attempt.failedAttempts = 0;
107 attempt.lockoutUntil = 0;
108 server.send(200, "text/html", "<h1>Hello, secure world!</h1><p>You are authenticated.</p>");
109 });
110
111 server.begin();
112 Serial.println("HTTPS server started on port 443");
113}
114
115void loop() {
116 server.handleClient();
117}
118