Both sides drew a blank in their final game in Group H, meaning Massimiliano Allegri's side clinched the second spot by a single point.
Milan captain Riccardo Montolivo was sent off for a lunge on Christian Poulsen after only 22 minutes, but Ajax was unable to secure the victory it needed to progress from Group H.
Poulsen was denied by the post before Montolivo saw red, and Serie A outfit Milan dug deep with a dogged defensive display to secure second place behind Barcelona.
Ajax was totally dominant but failed to make the most of its numerical advantage as it missed a golden opportunity to reach the last 16 for the first time in eight years and was forced to settle for a UEFA Europa League spot.
Milan striker Stephan El Shaarawy made his first start since August, while right back Mattia De Sciglio also returned in one of five changes made by Massimilano Allegri.
Poulsen, Bojan Krkic and Stefano Denswil all came in for Ajax, which started brightly and nearly took the lead in the fourth minute.
Manager Frank De Boer insisted the Eredivisie champions had nothing to lose at the San Siro, and they were only denied by the woodwork as Poulsen's glancing header struck the far post from a Lasse Schone corner.
Ajax was brimming with confidence and forced Milan goalkeeper Christian Abbiati to get down well to tip Davy Klaassen's header around the near post.
Milan's hopes of progressing to the last 16 then suffered a major setback when Montolivo was given his marching orders by referee Howard Webb for a reckless late challenge on Poulsen.
Allegri was forced into a reshuffle as a result, as El Shaarawy's comeback was short-lived, with Andrea Poli replacing him in a bid to bolster Milan's midfield.
De Boer replaced defensive midfielder Poulsen with striker Danny Hoesen at the break, and the visitors piled on the pressure at the start of the second half, with Viktor Fischer firing over the crossbar from the edge of the penalty area.
Klaassen then fired straight at a grateful Abbiati from 20 yards out as Ajax continued to probe and the tension mounted.
Abbiati was called into action again after 65 minutes to save with his feet to keep out Fischer's drilled right-footed strike after some lovely build-up play.
Klaassen spurned a great chance when he scuffed a shot wide of the far post 17 minutes from time as Ajax's frustration built and Denswil fired wide in a feisty finale.
Then midfielder Klaassen was narrowly off target with the last kick of the game as a gutsy Milan side stood firm on a frustrating night for the Dutch giants.