Manchester City had a late goal against Porto ruled out but a draw was enough for them to secure top spot in Group C.
It seemed that after a frustrating 80 minutes substitute Gabriel Jesus had broken the deadlock when he tapped home after his initial header had been saved, but the effort was ruled out because Joao Cancelo was offside.
The rest of the match saw exceptional goalkeeper Agustin Marchesin and his deep-lying five-man defence soak up incessant pressure from Pep Guardiola's side, who came into the match having put five goals past Burnley at the weekend and with a 100% record in the group.
The Argentine keeper made three superb saves. He twice denied Spanish forward Ferran Torres, pushing one effort wide of the post in the first half before blocking a spectacular overhead kick after the break.
Porto's stopper also denied Raheem Sterling by rushing out to block his attempt on goal. The England winger went close again when he cut in and fired a low shot which was cleared off the line by Zaidu Sanusi.